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

2022-09-03 07:34:17

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

网.xml

 <param-value>
    /WEB-INF/a_spring.xml
    /WEB-INF/b_spring.xml
 </param-value>

持久性.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>

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>

我还向b_spring.xml声明另一个实体ManagetFactory,Transaction Manager和dataSource。

错误

豆的初始化失败;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 没有类型 [javax.persistence.EntityManagerFactory] 的唯一 bean 定义:预期的单 bean 但发现 2 原因:org.springframework.beans.factory.NoSuchBeanDefinitionException: 没有类型的唯一 Bean [javax.persistence.EntityManagerFactory] 定义:预期的单豆,但在 org.springframework.beans.factory.BeanFactoryUtils.beanOfTypeIncludingAncestors(BeanFactoryUtils.java:303) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:451) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:428) at org.springframework.orm.jpa.support.PersistenceAnPostProcessor$AnnotatedMember.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:582) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$AnnotatedMember.resolve(PersistenceAnnotationBeanPostProcessor.java:553) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$AnnotatedMember.inject(PersistenceAnnotationBeanPostProcessor.java:489)


答案 1

在多数据源配置的情况下,我们需要定义哪一个将被视为主数据源。我们可以在java配置或XML Bean配置中使用注释来指定。@Primaryprimary=true

由于在 XML 中创建两个实体管理器,因此我们需要使用来指定应在何处注入哪个 Bean。在你的情况下,像这样的东西。@Qualifier

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

对于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"/>

答案 2

您是否尝试过提供包含您的EntityManagerFactory Bean的软件包详细信息?

您可以在 Bean 定义中将包详细信息作为属性提供 -

<property name="packagesToScan" value="com.XX.XX.XX.XX" />

要在此块中添加的新属性 -

<bean id="entityManagerFactory1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
           <property name="persistenceUnitName" value="db2" />     
        <property name="dataSource" ref="dataSource1"/>
  <-- add here for both beans  -->

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

此外,您还错过了该物业 -persistenceXmlLocation

 <property name="persistenceXmlLocation" value="***/persistence.xml" />

推荐