从外部Jar文件加载JPA实体

时间:2012-02-29 18:46:21

标签: spring hibernate jpa

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

我的基本问题是在persistence.xml上没有EntityManager查找,然后加载指定的属性,然后扫描所有包以获取@Entity注释?

任何关于它如何工作的见解以及如何解决这个问题都会很棒。

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

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

这是我的代码/配置

<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>

定义EnitityManagerFactory以启动实体管理器。

<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,它定义了二级缓存和其他hibernate属性。

然后,具有实体的模块。

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> {

4 个答案:

答案 0 :(得分:4)

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

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

Haven尝试但你可以为实体启用hibernate自动检测 <property name="hibernate.archive.autodetection" value="class, hbm"/>

答案 1 :(得分:2)

如果您使用的是spring boot,请在主springboot类中使用实体扫描注释

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

答案 2 :(得分:1)

在工作中我们不使用JPA而是使用Hibernate,我们的项目完全模块化。 我们处理大约30个不使用相同模块的国家,我们只需更改maven依赖项(没有要修改的orm文件)就可以在会话工厂中加载所有这些模块的实体。

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

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

还检查如何使用Spring创建EMF: AbstractEntityManagerFactoryBean

修改:您可以查看:using the MergingPersistenceUnitManager to load entity

答案 3 :(得分:1)

只需使用

@EntityScan("com...pakage-which-contains-entities...")

或者,如果您有多个实体包,请使用

@EntityScan(basePackages = {"...pkg1...", "...pkg2..."} )