2012-02-29 114 views
6

我有一个项目设置,其中我已经模块化一个项目,并将一个模块打包到一个jar文件中,当我们创建一个war并部署它时,它将包含在主项目中。 我面临的问题是,我有一个实体存在于模块中,该模块在启动期间构建unitName的JPA Container EntityManagerFactory时未加载。从外部Jar文件加载JPA实体

我所拥有的基本问题是在persistence.xml中不执行EntityManager查找,然后加载指定的属性,然后扫描@Entity注释的所有包?

任何有关如何工作,以及如何解决这个问题的意见将是伟大的。

我发现这个链接,它提到了创建独立的persistenceUnits,但在这里我不需要一个单独的持久单元。我只需要模块捎带父项目并加载实体和其他@Resource,@Component类,由于上下文:组件扫描和注释配置。

http://javathoughts.capesugarbird.com/2009/02/jpa-and-multiple-persistence-units.html

这里是我的代码/配置EnitityManagerFactory的

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceUnitName" value="LineManagement" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="generateDdl" value="false" /> 
      <property name="showSql" value="false" /> 
      <property name="databasePlatform" ref="cpsHibernateDialectClassName" /> 
     </bean> 
    </property> 
    <property name="beanName" value="entityManager"></property> 
</bean> 

定义启动实体管理器。

<persistence-unit name="LineManagement" transaction-type="RESOURCE_LOCAL"> 
    <properties> 
     <property name="hibernate.id.new_generator_mappings" value="true" /> 
     <property name="hibernate.current_session_context_class" value="thread" /> 
     <property name="hibernate.default_batch_fetch_size" value="200" /> 

....

的persistence.xml限定第二级高速缓存和其它休眠特性。

然后,该模块具有一个实体。

import javax.persistence.Entity; 


@Entity 
@Table(name = IntegrationEvent.TABLE_NAME, uniqueConstraints = @UniqueConstraint(columnNames = "INTGRTN_EVNT_QUEUE_SK")) 
@GenericGenerator(name = "UUID_GEN", strategy = "org.hibernate.id.UUIDHexGenerator",  parameters = { @Parameter(name = "separator", value = "-") }) 
public class IntegrationEvent implements Serializable { 

.... }

注:该实体是在不同的包比亲本,因为它是在其自己的一个单独的模块。

在主项目中加载正常的实体。

package com.parent.line.entity; 

import javax.persistence.Entity; 

@Entity 
@Table(name = "ACCOUNT") 
@Cacheable(true) 
public class Account 
    implements LMLookupTypeEntityByDivision, Serializable, Comparable<Account> { 
+1

问题是因为我将模块作为依赖添加到我的父项目中,因为它完全分离。因此它会放在我的WEB-INF/lib文件夹中。在调试加载实体的JPA代码后,我意识到它开始扫描@Entity注释的类路径来自WEB-INF/classes。这是有道理的,因为lib是只读的。现在,我不得不考虑在classes文件夹中添加模块,或者在persistence.xml中使用标记,以便使jar实体能够被扫描和加载 – Hrishikesh 2012-03-01 17:57:20

回答

4

要扫描驻留在jar中的实体,必须将其包含在persistence.xml中。 <jar-file>packedEntity.jar</jar-file>

如果你想从包中加载单元,那么你可以尝试直接从jar中注入它。 @PersistenceContext(unitName = "../packedEntity.jar#main")

没有尝试过,但您可以为实体 <property name="hibernate.archive.autodetection" value="class, hbm"/>

1

在工作中我们不使用JPA,但Hibernate的Hibernate的自动检测,我们的项目是完全模块化的。 我们处理大约30个国家不使用相同的模块,我们能够通过简单地改变maven依赖关系(无需修改orm文件)在会话工厂中加载所有这些模块的实体。

使用的解决方案是使用Java SPI。 ServiceLoader将查找实现核心接口EntityProvider的类。 每个模块的每个EntityProvider将硬编码它所带来的实体,并在调用ServiceLoader.load(EntityProvider.class)时返回一个实体列表。 因此,在平台核心中,我们只需创建一个基于弹簧的会话工厂,在该工厂中我们通过将调用SPI的工厂bean提供实体列表。

我不知道JPA是否会很容易,但我很确定这是可能的,但您可能需要手动创建EMF从春天的上下文,还有PersistenceUnit我猜...你可能会want是一个持久化单元,它是所有模块的持久化单元的“合并”(至少对于你的实体) 看看SPI和javax.persistence.spi包。

检查还怎么与Spring创建一个EMF: AbstractEntityManagerFactoryBean

编辑:您可以检查此:using the MergingPersistenceUnitManager to load entity

0

如果您使用的春天开机使用实体扫描注释在主springboot类

@EntityScan(
     basePackageClasses = {externalpackage.classname.class} 
)