JPA 多重持久性单元错误

发布于 2024-08-14 07:11:21 字数 3115 浏览 2 评论 0原文

我试图在我的项目中添加一个数据库/架构/persistenceUnit,但收到错误:

未定义 [javax.persistence.EntityManagerFactory] ​​类型的唯一 bean:预期为单个 bean,但发现了 2 个

我 google/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 吗?

我将我的挖掘的一些笔记放在春季论坛中(LINK

好吧,就是这样...任何帮助都会很高兴!

I'm trying to add one more database/schema/persistenceUnit in my project and I'm receiving the error:


No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2

I google/api allot and could not found why spring is complaining about my configuration.

Here is part of my 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"/>


Some questions:

  • Do I need to have two tx:annotation-driven ?
  • Do I need to specify persistenceUnitName in the factory ?

I'm putting some notes of my digg in spring forum (LINK)

Well thats it... any help will be glad!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦归所梦 2024-08-21 07:11:21

使用 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 在内部创建和使用。”

With Spring, you need to have only one EntityManagerFactory.
What you are looking for is describe in the Spring documentation at the chapiter 13.5.1.4 : "Deals with multiple persitence units"

I copy/paste the text :

"13.5.1.4 Dealing with multiple persistence units

For applications that rely on multiple persistence units locations, stored in various JARS in the classpath, for example, Spring offers the PersistenceUnitManager to act as a central repository and to avoid the persistence units discovery process, which can be expensive. The default implementation allows multiple locations to be specified that are parsed and later retrieved through the persistence unit name. (By default, the classpath is searched for META-INF/persistence.xml files.)

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

The default implementation allows customization of the PersistenceUnitInfo instances, before they are fed to the JPA provider, declaratively through its properties, which affect all hosted units, or programmatically, through the PersistenceUnitPostProcessor, which allows persistence unit selection. If no PersistenceUnitManager is specified, one is created and used internally by LocalContainerEntityManagerFactoryBean."

孤芳又自赏 2024-08-21 07:11:21

此异常意味着您正在尝试按类型自动装配 EntityManagerFactory。您的代码中是否有 @Autowired 注释?

同样,当使用 @PersistenceContext 时,请正确设置 unit 属性。并且(我不确定这是否正确)-尝试将 name 属性设置为您各自的工厂名称。

另外,检查您是否没有错误地复制粘贴 REST 事务管理器 - 现在没有这样的 bean REST

This exceptions means that you are trying to autowire EntityManagerFactory by type. Do you have any @Autowired annotation in your code?

Aslo, when using @PersistenceContext, set the unit attribute correctly. And (I'm not sure if this is a proper thing to do) - try setting the name attribute to your respective factory name.

Also, check if you haven't copy-pasted incorrectly the REST transaction manager - now there is no such bean REST

输什么也不输骨气 2024-08-21 07:11:21

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

Ensure all of your @PersistenceContext specify unitName. I haven't figured out how to tell Spring that a particular EMF or PersistenceUnit is the default. I thought specifying primary="true" on the default EMF would work but doesn't appear to

风向决定发型 2024-08-21 07:11:21

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

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

更多问题的核心,请参阅 SPR-3955。总而言之,Spring 3.0M4 之前的版本不支持使用 @Transactional 的多个事务管理器。我也不相信它尊重 @PersistenceContext 的“unitName”属性,因此您也无法指定该属性。

有关我如何通过显式注入 EntityManagerFactory 并使用 AOP 重新启用 @Transactional 来解决此问题的示例,请参阅com/lhanson/multipleEntityManagers" rel="nofollow">我的示例应用程序

Do I need to specify persistenceUnitName in the factory ?

If you've got multiple persistence units, you do need to specify which ones the factories will use.

More to the heart of the matter, see SPR-3955. To summarize, versions prior to Spring 3.0M4 do not support multiple transaction managers with @Transactional. Nor do I believe it honors the "unitName" attribute for @PersistenceContext, so you can't specify that either.

For an example of how I worked around this by explicitly injecting EntityManagerFactorys and using AOP to re-enable @Transactional, see my sample app

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文