1. 程式人生 > >spring+jpa 兩個資料來源配置

spring+jpa 兩個資料來源配置

1. META-INF/persistence.xml :

<persistence 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/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="aaaUnit"  transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <properties>
   <property name="hibernate.hbm2ddl.auto" value="update" />
   <property name="hibernate.jdbc.fetch_size" value="18" />
   <property name="hibernate.jdbc.batch_size" value="10" />
   <property name="hibernate.show_sql" value="false" />
   <property name="hibernate.format_sql" value="true" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
   </properties>
    </persistence-unit>

 <!-- *********************************************** -->
   
    <persistence-unit name="bbbUnit" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <properties>
   <property name="hibernate.hbm2ddl.auto" value="update" />
   <property name="hibernate.jdbc.fetch_size" value="18" />
   <property name="hibernate.jdbc.batch_size" value="10" />
   <property name="hibernate.show_sql" value="false" />
   <property name="hibernate.format_sql" value="true" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
  </properties>
    </persistence-unit>   
</persistence>

2.applicationContext.xml

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
   
 <bean id="userService" class="hr.gov.serviceImpl.userServiceImpl"/>    
    
    
    
    <!-- ******************************************************** -->
  
   

 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
   <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/aaa?useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=round" />
    <property name="user" value="" />
    <property name="password" value=""/>
    <property name="minPoolSize" value="1" />
    <property name="maxPoolSize" value="20"/> 
    <property name="initialPoolSize" value="1"/>
    <property name="maxIdleTime" value="25000"/>
    <property name="acquireIncrement" value="1"/>
    <property name="acquireRetryAttempts" value="30"/>
    <property name="acquireRetryDelay" value="1000"/>
    <property name="testConnectionOnCheckin" value="true"/>
    <property name="automaticTestTable" value="c3p0TestTable"/>
    <property name="idleConnectionTestPeriod" value="18000"/>
    <property name="checkoutTimeout" value="3000"/>
 </bean>
 
 <bean id="entityManagerFactory" autowire="byName"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="aaaUnit" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="MYSQL" />
                <property name="showSql" value="false" />
            </bean>
        </property>
    </bean>
 
  <!-- 事務管理 -->
  <bean id="transactionManager"
   class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory"  ref="entityManagerFactory" />
  </bean>
 
  <!-- 將事務管理加到標有 @Transactional 的類或者方法上 -->
  <tx:annotation-driven transaction-manager="transactionManager" />


<!-- ********************************************************* -->

 <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/bbb?useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=round" />
    <property name="user" value="" />
    <property name="password" value="" />
    <property name="minPoolSize" value="1" />
    <property name="maxPoolSize" value="20"/> 
    <property name="initialPoolSize" value="1"/>
    <property name="maxIdleTime" value="25000"/>
    <property name="acquireIncrement" value="1"/>
    <property name="acquireRetryAttempts" value="30"/>
    <property name="acquireRetryDelay" value="1000"/>
    <property name="testConnectionOnCheckin" value="true"/>
    <property name="automaticTestTable" value="c3p0TestTable"/>
    <property name="idleConnectionTestPeriod" value="18000"/>
    <property name="checkoutTimeout" value="3000"/>
  
 </bean>
 
  <bean id="entityManagerFactory2" autowire="byName"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="bbbUnit" />
        <property name="dataSource" ref="dataSource2" />
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="MYSQL" />
                <property name="showSql" value="false" />
            </bean>
        </property>
    </bean>

  <!-- 事務管理 -->
  <bean id="transactionManager2"
   class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory"  ref="entityManagerFactory2" />
  
  </bean>
 
  <!-- 將事務管理加到標有 @Transactional 的類或者方法上 -->
  <tx:annotation-driven transaction-manager="govtransactionManager2" />
 
 
 
</beans>

3. dao註解管理事務

建立兩個baseDaoImpl:

public EntityManager entityManager;
 
 private EntityManagerFactory emf;
 public EntityManager getEntityManager() {
  return entityManager;
 }
 
 @PersistenceContext(unitName="aaaUnit")
 public void setEntityManager(EntityManager entityManager) {
  this.entityManager = entityManager;
 }

 @PersistenceUnit(unitName="aaaUnit")
 public void setEntityManagerFactory(EntityManagerFactory emf) {
  this.emf = emf;
 }

baseDaoImpl2:

public EntityManager entityManager;
 
 private EntityManagerFactory emf;
 public EntityManager getEntityManager() {
  return entityManager;
 }
 
 @PersistenceContext(unitName="aaaUnit")
 public void setEntityManager(EntityManager entityManager) {
  this.entityManager = entityManager;
 }

 @PersistenceUnit(unitName="aaaUnit")
 public void setEntityManagerFactory(EntityManagerFactory emf) {
  this.emf = emf;
 }

用兩個dao分開連結資料庫。

實現類繼承basedao或basedao2即可。

補充:service新增事務工廠,則需要改變一些配置。

1.兩個資料庫對應的事務各新增一句   <qualifier value="aaaEM" />
例如:

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

2. 新增之後,會提示出錯,不支援qualifier 。

則將applicationContext.xml的頭部更改為:

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

到此完成。

配置過程中遇到的問題

配置完成後,啟動專案應該達到自動建立資料庫的效果。

控制檯列印錯誤:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2

如果認真觀察的話,上面應該還會提示在建立哪個bean的時候提示出錯。

那麼提示錯誤的bean裡面應該有用到EntityManagerFactory。

解決辦法:對set方法添加註解,如:

@PersistenceUnit(unitName="aaaUnit")
 public void setEntityManagerFactory(EntityManagerFactory emf) {
  this.emf = emf;
 }

這樣來區分資料來源。

重啟,ok。