Melad Basilius
Melad Basilius

Reputation: 4306

Inject 2 (3 in the near future) different entityManagerFactory (or entityManager) in spring application

I have Spring + JPA (Hibernate) project, at which i connect to MsSQL database, now i need to open a new connection but this time it will be for MySQL. i am using XML configuration

<bean id="hibernateJpaVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${spring.datasource.driverClassName}" />
   ....
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="dataSource" p:packagesToScan="com.wsg.admin.api.model"
    p:jpaVendorAdapter-ref="hibernateJpaVendorAdapter">

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.cache.use_second_level_cache">false</prop>
            ....
        </props>
    </property>
</bean>

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

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

<!-- Configure the MySQL connection -->
<bean id="enduserDataSource" class="org.apache.commons.dbcp2.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${enduser.db.driver}" />
    ....
</bean>

<bean id="enduserEntityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="enduserDataSource" p:packagesToScan="com.wsg.admin.api.model"
    p:jpaVendorAdapter-ref="hibernateJpaVendorAdapter">

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.cache.use_second_level_cache">false</prop>
            ....
        </props>
    </property>
</bean>

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

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

then i try to inject the entityManager using the fragment

@Autowired
EntityManager entityManager;

but i get exception

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandServiceImpl': Unsatisfied dependency expressed through field 'entityManager'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected single matching bean but found 2: org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1

Upvotes: 1

Views: 712

Answers (2)

Melad Basilius
Melad Basilius

Reputation: 4306

Fixed. Thanks to @Volceri i used the answer https://stackoverflow.com/a/18073628/1973933, as follow

add <property name="persistenceUnitName" value="appPU" /> to each of entityManagerFactory

<bean id="entityManagerFactory" ...  >

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.cache.use_second_level_cache">false</prop>
            ...
        </props>
    </property>
    <property name="persistenceUnitName" value="dataSourcePU" />
</bean>

<bean id="endUserEntityManagerFactory" ...  >

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.cache.use_second_level_cache">false</prop>
            ...
        </props>
    </property>
    <property name="persistenceUnitName" value="enduserDataSourcePU" />
</bean>

and to inject the em objects, i used

@PersistenceContext(unitName="dataSourcePU")
EntityManager entityManager;

@PersistenceContext(unitName="enduserDataSourcePU")
EntityManager endUserEntityManager;

Upvotes: 0

pvpkiran
pvpkiran

Reputation: 27018

Since you have two Entity Manager's(From EntityMangaerFactory) you need to tell spring which specifix EntityManager you want to be Autowired. Use @Qualifier

@Autowired  
@Qualifier("enduserEntityManagerFactory")  // use bean id of the Entity Manager Factory you want to inject
EntityManagerFactory entityManagerFactory

EntityManager entityManager = entityManagerFactory.createEntityManager();

More about this here

Upvotes: 2

Related Questions