如何使用Spring和JPA设置多个数据源

Hoo*_*Hoo 16 java spring jpa jndi entitymanager

在我们的应用程序中,我们希望使用Spring和JPA设置多个数据源.因此我们创建了2个entityManagerFactory,2个数据源和2个事务管理器.

web.xml中

 <param-value>
    /WEB-INF/a_spring.xml
    /WEB-INF/b_spring.xml
 </param-value>
Run Code Online (Sandbox Code Playgroud)

persistence.xml中

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="db1" transaction-type="RESOURCE_LOCAL">
        <class>com.rh.domain.RcA</class>
    </persistence-unit>

      <persistence-unit name="db2" transaction-type="RESOURCE_LOCAL">
      <class>com.rh.domain.Rcb</class>
    </persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)

a_spring.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:tx="http://www.springframework.org/schema/tx" 
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

      <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>  
      <bean id = "RcMaintenanceService" class="com.rh.services.RcAbcMaintenanceServiceImpl" autowire="byName" />

    <aop:config>
            <aop:pointcut id="rOperation" expression="execution(* com.rh.services.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="rOperation"/>
        </aop:config>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                   <tx:method name="*"/>
            </tx:attributes>
        </tx:advice>

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:comp/env/jdbc/db1" />
        </bean> 
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
            <property name="dataSource" ref="dataSource"/>
        </bean>

        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
               <property name="persistenceUnitName" value="db1" />     
            <property name="dataSource" ref="dataSource"/>
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
                    <property name="showSql" value="true"/>
                    <property name="generateDdl" value="false"/>
                    <property name="database" value="MYSQL" />
                    <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
                </bean>
            </property>
            <property name="jpaDialect">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect">
                </bean>
            </property>
        </bean>
Run Code Online (Sandbox Code Playgroud)

我还将另一个entityManagetFactory,Transaction Manager和dataSource声明为b_spring.xml.

错误

bean的初始化失败; 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义类型为[javax.persistence.EntityManagerFactory]的唯一bean:期望的单个bean但找到2引起的:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有唯一的bean类型为[javax.persistence.EntityManagerFactory]的定义:预期的单个bean但在org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor的org.springframework.beans.factory.BeanFactoryUtils.beanOfTypeIncludingAncestors(BeanFactoryUtils.java:303)中找到2个. findOfaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:451)atg.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:428)org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor $ AnnotatedMember.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java: 582)在org.springframework.orm.jpa.suppo orrt.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor $ AnnotatedMember.inject(PersistenceAnnotationBeanPostProcessor.java:489)中的rt.PersistenceAnnotationBeanPostProcessor $ AnnotatedMember.resolve(PersistenceAnnotationBeanPostProcessor.java:553)

luc*_*cid 7

在多数据源配置的情况下,我们需要定义哪一个将被视为主数据源.我们可以@Primary在java config或primary=trueXML bean config中指定使用注释.

由于有两个实体管理器是用XML创建的,我们需要使用它@Qualifier来指定应该将哪个bean注入到哪里.在你的情况下,这样的事情.

@PersistenceContext(unitName = "db1")
public void setEntityManager(@Qualifier("entityManagerFactory") EntityManager entityMgr) {
    this.em = entityMgr;
}
Run Code Online (Sandbox Code Playgroud)

对于XML配置,我们可以做这样的事情

<bean id="BaseService" class="x.y.z.BaseService">
    <property name="em" ref="entityManagerFactory"/>
    <property name="em1" ref="entityManagerFactory1"/>
</bean>

<bean id = "RcMaintenanceService" class="com.rh.services.RcAbcMaintenanceServiceImpl" autowire="byName" parent="BaseService"/>
Run Code Online (Sandbox Code Playgroud)