Spring context unable to resolve among multiple entity managers

607 views Asked by At

I have a module A that has its own EntityManager em. This module is a dependency in other module B. Module B interacts with two instances of same db,and based on business logic I decide which record to store in which db. For this I have two entity managers em1 and em2. On deploying the error comes like:

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.

Why is module B not independent of the EntityManager of the dependent modules? What should be the correct way?

1

There are 1 answers

0
Philip On

configurations for module 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>

persistence.xml for module A

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

for some reason all the entities of moduleA, we keep in 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"/>

Configuration for module B which has to interact with two instances of the same database.

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

persistence.xml of module B

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

Class in module B that provides me the entity managers at runtime

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

On deployment, we get exceptions for module A like expected single matching bean but found 3: em,em1,em2. Its not able to resolve which entitymanager should be used for moduleA. My question is, since module A is added as a dependency in module B, its entity managers should be independent of module B.