JPA - 定义@Entity对象的多个jar

时间:2011-09-16 09:35:33

标签: hibernate jpa annotations entity

我们正在以一种非常模块化的方式开发一个使用Spring,Hibernate和Maven的Web应用程序。有定义数据访问和查看特定内容的核心项目,然后有定义逻辑和实体的模块(@Entity),然后是定义控制器和视图的Web应用程序。

现在我们有一个安全模块,用于定义帐户和角色等安全实体,我们有一个原型模块,用于定义客户和订单等一些示例实体。两者都在PersistenceUnit内定义persistence.xml,除了PersistenceUnit名称之外几乎是空的,因为所有数据库配置都是在带有datasource.xml的Web应用程序中完成的。 Web应用程序应该将两个jar加载为maven依赖项。

这两个项目都可以构建好的,自动扫描所有实体并为各自的单元测试创​​建它们。如果单独添加,它们也将成功加载到Web应用程序中。

但是,只要两者同时加载,第二个将覆盖第一个PersistenceUnit,从而为第一个实体创建IllegalArgumentException : Not an entity。如果两个项目都有不同的持久性单元,则加载Web应用程序将引发另一个例外,即no single default persistence unit已定义。

那么......我如何才能在我的网络应用中加载所有@Entity注释类,而不必在persistence.xml内部定义它们(如here),而是通过组件扫描? This似乎是一个想法,虽然我不知道如何使用和测试它......

我认为我们要么必须在Web应用程序中合并所有PersistenceUnits,要么以编程方式加载所有实体。在persistence.xml中定义硬编码不是我们的选择。

5 个答案:

答案 0 :(得分:4)

我们使用类似的模块布局, 但是我们将持久化上下文放在应用程序的war部分中,并将实体管理器注入到模块的DAO中。 除单元测试外, 模块没有PU。 我们这样做是因为我们害怕, 跨越多个模块的事务可能会造成麻烦。

在DAO中

@PersistenceContext
private EntityManager em;

在persistance.xml中,您需要使用元素登记所有实体。

<persistence-unit name="myPU">
    <class>com.Entity1</class>      
<class>com.Entity2</class>

答案 1 :(得分:4)

由于这个问题似乎仍然引起关注,我将发布我们最新的解决方案。

我们现在自动扫描所有软件包,而不是在任何地方使用persistence.xml 文件。

在我们的datasource.xml中,我们添加了一行

<property name="packagesToScan" value="our.basepackage" />

几乎完整的datasource.xml:

<!-- Bean definition here -->

<bean id="ourDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <!-- define connection properties -->       
</bean>


<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="ourDataSource" />
    <property name="packagesToScan" value="our.basepackage" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="false" />
            <property name="generateDdl" value="true" />
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
        </bean>
    </property>

</bean>

<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />

答案 2 :(得分:3)

这些类将在类加载器中。

这样回答Scanning Java annotations at runtime

这就是你想要的吗?要扫描注释的@Entity并将其添加到PersistenceUnit

问候。

答案 3 :(得分:3)

嗯,我们在开发周期中遇到了类似的问题。如果您的引用实体位于另一个-ejb.jar文件中(这是我们的情况),您可以使用

绑定这些实体

<jar-file>relativePathToYourJar/dependent-entities-ejb.jar</jar-file>

标签。请注意,您还应在dependent-entities-ejb.jar META-INF 文件夹下包含 persistence.xml 。可以找到更多信息here

答案 4 :(得分:0)

我已经制作了像tugcem这样的解决方案,但由于我使用Maven,我不愿意在persistence.xml中使用jar版本号。我想出的解决方案在这里描述:JPA 2.0: Adding entity classes to PersistenceUnit *from different jar* automatically