【问题标题】:Spring context unable to resolve among multiple entity managersSpring 上下文无法在多个实体管理器之间解析
【发布时间】:2015-06-10 05:34:37
【问题描述】:

我有一个模块 A,它有自己的 EntityManager em。该模块是其他模块 B 中的依赖项。模块 B 与同一数据库的两个实例交互,并根据业务逻辑决定将哪个记录存储在哪个数据库中。 为此,我有两个实体管理器 em1 和 em2。 部署错误如下:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.moduleA.moduleAclass com.moduleA.moduleAclass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'moduleAclass': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 3: em,em1,em2.

为什么模块 B 不独立于依赖模块的 EntityManager?正确的方法应该是什么?

【问题讨论】:

  • 你必须使用@Qualifier注解来定义你想要使用的bean。
  • 我可以在我的模块 B 中做到这一点,并且正在这样做。但问题是当我部署模块 B 时,依赖模块 A 中存在冲突,这是我没想到的。
  • 显示一些代码。您是否注入了指定 unitName 属性的 PersistenceContext?
  • 在下面添加了代码。请参考

标签: spring hibernate jpa spring-data-jpa entitymanager


【解决方案1】:

模块 A 的配置

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

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="moduleApersistenceUnit" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="MYSQL" />

        </bean>
    </property>
</bean>

模块 A 的persistence.xml

<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="moduleApersistenceUnit"
    transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
    </properties>
</persistence-unit>
</persistence>

由于某种原因,moduleA 的所有实体都保存在 moduleAentities-persistence.xml 中

<entity-mappings version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd">
<description>The minimal mappings for a persistent entity in XML.</description>
<entity name="moduleAentity1" class="com.moduleA.entity.moduleAentity1"/>   
<entity name="moduleAentity2" class="com.moduleA.entity.moduleAentity2"/>

必须与同一数据库的两个实例交互的模块 B 的配置。

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

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

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

 <bean id="entityManagerFactory2"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:META-INF/normalization-persistence.xml" />
    <property name="persistenceUnitName" value="fluxPersistenceUnit2" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="MYSQL" />

        </bean>
    </property>
</bean>
<bean id="entityManagerFactory1"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:META-INF/normalization-persistence.xml" />
    <property name="persistenceUnitName" value="fluxPersistenceUnit1" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="MYSQL" />

        </bean>
    </property>
</bean> 

模块 B 的persistence.xml

<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="moduleBpersistenceUnit1"
    transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>moduleAentities-persistence.xml</mapping-file>
    <class>com.moduleB.class1</class>
    <class>com.moduleB.class2</class>       
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
    </properties>
</persistence-unit>

<persistence-unit name="moduleBpersistenceUnit2"
    transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>moduleAentities-persistence.xml</mapping-file>
    <class>com.moduleB.class1</class>
    <class>com.moduleB.class2</class>       
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
    </properties>
</persistence-unit>

模块 B 中的类,在运行时为我提供实体管理器

public class EntityManagerProducer {
  @PersistenceContext(unitName = "moduleBpersistenceUnit1")
  private EntityManager modBEntityManager1;
  @PersistenceContext(unitName = "moduleBpersistenceUnit2")
  private EntityManager moduleBEntityManager2;

  public EntityManager getEntityManager(String userID) {
    if (userID % 4 ==0) {
      return modBEntityManager1;
    } else{
          return rawresponseEntityManager;
    }
  }
}

在部署时,我们得到模块 A 的异常,例如预期的单个匹配 bean,但发现 3:em、em1、em2。它无法解析应该为模块A 使用哪个实体管理器。我的问题是,由于模块 A 是作为模块 B 中的依赖项添加的,因此它的实体管理器应该独立于模块 B。

【讨论】:

    猜你喜欢
    • 2015-01-24
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多