JPA多持久化单元错误

6

我试图在我的项目中添加一个数据库/模式/持久单元,但是我收到了以下错误:

没有定义唯一类型为[javax.persistence.EntityManagerFactory]的bean:期望单个bean但找到2个

我搜索了很多谷歌/ API,但无法找到Spring抱怨我的配置的原因。

这是我的applicationContext.xml的一部分:

  <bean id="entityManagerFactory" 
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="transactionManager" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${show.hibernate.sql}" />
                <property name="generateDdl" value="false" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
            </bean>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" ...
        <property name="testOnBorrow" value="true" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

<bean id="entityManagerFactoryREST" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSourceREST" />
    <property name="persistenceUnitName" value="REST" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="${show.hibernate.sql}" />
            <property name="generateDdl" value="false" />
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
        </bean>
    </property>
</bean>

<bean id="dataSourceREST" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${database.driver}" />
    ...
    <property name="testOnBorrow" value="true" />
</bean>

<bean id="transactionManagerREST" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactoryREST" />
</bean>

<tx:annotation-driven transaction-manager="REST"/>
<tx:annotation-driven transaction-manager="transactionManager"/>

一些问题:

  • 我需要两个tx:annotation-driven吗?
  • 我需要在工厂中指定persistenceUnitName吗?

我在Spring论坛上记录了一些笔记(链接

就是这样...任何帮助都将受到欢迎!


你的第一个实体管理器定义不可见,而且很棘手 ;) (已修复) - Bozho
请提供您在代码中使用的 @PersistenceContext 用法。 - Bozho
4个回答

3
使用Spring框架时,只需要一个EntityManagerFactory。 你所寻找的内容在Spring文档的第13.5.1.4章节中有描述:“处理多个持久化单元”。 我复制/粘贴了该文本: “13.5.1.4处理多个持久化单元 对于依赖于多个持久化单元位置(例如存储在类路径中的各种JAR文件中)的应用程序,Spring提供了PersistenceUnitManager作为集中存储库,并避免持久化单元发现过程,这可能是昂贵的。默认实现允许指定多个位置,这些位置将被解析并通过持久化单元名称稍后检索。(默认情况下,会在类路径中搜索META-INF/persistence.xml文件。)”
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  <property name="persistenceXmlLocations">
    <list>
     <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
     <value>classpath:/my/package/**/custom-persistence.xml</value>
     <value>classpath*:META-INF/persistence.xml</value>
    </list>
  </property>
  <property name="dataSources">
   <map>
    <entry key="localDataSource" value-ref="local-db"/>
    <entry key="remoteDataSource" value-ref="remote-db"/>
   </map>
  </property>
  <!-- if no datasource is specified, use this one -->
  <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitManager" ref="pum"/>
  <property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

默认实现允许通过属性来自定义PersistenceUnitInfo实例,在将它们提供给JPA提供程序之前,这些属性会影响所有托管的单元。也可以通过PersistenceUnitPostProcessor编程方式进行自定义,以允许选择持久化单元。如果未指定PersistenceUnitManager,则会创建一个并由LocalContainerEntityManagerFactoryBean内部使用。


1
这个异常意味着您正在尝试按类型自动装配EntityManagerFactory。您的代码中是否有任何@Autowired注释?
此外,在使用@PersistenceContext时,请正确设置unit属性。并且(我不确定这是否是正确的做法)- 尝试将name属性设置为相应的工厂名称。
还要检查一下是否错误地复制了REST事务管理器 - 现在没有这样的bean REST

我的代码中没有@Autowired注解,我总是使用:<br> @PersistenceContext private EntityManager em; - rafa.ferreira
<tx:annotation-driven transaction-manager="REST" /> - 看起来不太对。 - Bozho
我明白如果在使用@PersistenceContext时没有指定unitName将会使用默认值,请查看此链接:http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html#transaction-declarative-annotations,注意提示。 - rafa.ferreira
哪个是默认的?有两个实体管理工厂。 您提供的链接是关于 @Transactional,而不是 @PersistenceContext。 - Bozho
是的,抱歉Bozho,实际上我想在这个链接中查找的是关于是否需要在tx:annotation-driven中指定名称的信息。抱歉我的错误! - rafa.ferreira

0

确保您的@PersistenceContext指定unitName。我还没有弄清楚如何告诉Spring特定的EMF或PersistenceUnit是默认值。我认为在默认EMF上指定primary="true"会起作用,但似乎并不起作用。


0

我需要在工厂中指定persistenceUnitName吗?

如果您有多个持久性单元,确实需要指定工厂将使用哪些单元。

更重要的是,请参见SPR-3955。总结一下,Spring 3.0M4之前的版本不支持具有@Transactional的多个事务管理器。我也不相信它会尊重@PersistenceContext的“unitName”属性,因此您也无法指定它。

关于如何通过显式注入EntityManagerFactory并使用AOP重新启用@Transactional的示例,请参见我的示例应用程序


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接