使用Spring + Hibernate + JPA的多个数据库模式

时间:2016-12-02 11:45:25

标签: spring hibernate spring-mvc jpa

我有相同的数据库模式database_1和database_2,并希望配置这两个数据库(数据库模式相同)并决定使用哪个数据库的运行时间。
我的 persistence.xml 如下所示:

 <persistence-unit name="first" transaction-type="RESOURCE_LOCAL">
     <provider>org.hibernate.ejb.HibernatePersistence</provider>
     <class>com.model.AboutUs</class>
     <class>com.model.AccessCards</class>
           <properties>
        <property name="hibernate.dialect" value="com.util.customMySQLDialect" />
        <property name="hibernate.hbm2ddl.auto" value="none" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
        <property name="hibernate.jdbc.batch_size" value="20"/>
        <property name="hibernate.cache.use_query_cache" value="true"/>
        <property name="hibernate.cache.use_second_level_cache" value="true"/>
          </properties>
</persistence-unit>

持久性名称second在此处配置如下:

<persistence-unit name="second" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.model.AboutUs</class>
    <class>com.model.AccessCards</class>
            <properties>
        <property name="hibernate.dialect" value="com.util.customMySQLDialect" />
        <property name="hibernate.hbm2ddl.auto" value="none" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
        <property name="hibernate.jdbc.batch_size" value="20"/>
        <property name="hibernate.cache.use_query_cache" value="true"/>
        <property name="hibernate.cache.use_second_level_cache" value="true"/>
           </properties>
</persistence-unit>

两个持久性单元都加载相同的类。 现在我的database-configure.xml就像我用数据源配置持久性单元一样。如下所示,第一个持久性单元名称配置为数据源名称数据源为:

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

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="first" />
    <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${datasource.driverClassName}" />
    <property name="jdbcUrl" value="${datasource.url}" />
    <property name="user" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="acquireIncrement" value="1" />
    <property name="acquireRetryAttempts" value="1" />
    <property name="maxIdleTime" value="300" />
    <property name="maxPoolSize" value="20" />
    <property name="minPoolSize" value="3" />
    <property name="maxStatements" value="300" />
    <property name="testConnectionOnCheckin" value="true" />        
</bean>

现在这个代码用于配置第二个持久性单元名称,数据源名称为datasource5,如下所示:

    <bean id="transactionManager5" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory5" />
</bean>
   <bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource5" />
    <property name="persistenceUnitName" value="second" />
    <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
</bean> 
<bean id="dataSource5"    class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${datasource.driverClassName}" />
    <property name="jdbcUrl" value="${datasource5.url}" />
    <property name="user" value="${datasource5.username}" />
    <property name="password" value="${datasource5.password}" />
    <property name="acquireIncrement" value="1" />
    <property name="acquireRetryAttempts" value="1" />
    <property name="maxIdleTime" value="300" />
    <property name="maxPoolSize" value="20" />
    <property name="minPoolSize" value="3" />
    <property name="maxStatements" value="300" />
    <property name="testConnectionOnCheckin" value="true" />        
</bean>

现在我使用实体管理器在数据库中保存数据,我正在使用mysql数据库。我得到了持久性单元名称第一和第二的实体管理器。

@PersistenceContext(unitName="first")
private EntityManager entityManager;


@PersistenceContext(unitName="second")
private EntityManager entityManager2;

现在,实体管理器已成功使用persist(object)方法将数据保存在数据库中。     entityManager.persist(项目);

和entityManager2成功使用persist(object)方法将数据保存在数据库中(此处为No Exception)。但是数据不存储在数据库datbase_2中。

entityManager2.persist(project);

如果我在persistence.xml中第一个和第二个更改持久性单元的顺序,则entityManager2将数据保存在数据库中,而entitymanager不会将数据保存在数据库中。
任何人都知道如何为同一个数据库模式创建多个实体管理器。

1 个答案:

答案 0 :(得分:0)

有一些限制:

  1. @Transactional对应单个TransactionManager。
  2. JpaTransactionManager对应单个EntityManager(Factory)。
  3. 因此,为每个事务管理器使用带有@Transactional注释的单独方法:

    @Transactional(transactionManager = "tmBeanName")
    

    之后,实体经理将正常工作。

    此外,还有一些解决方法可以打破第二个限制(在这种情况下不要使用它):

      

    可以使用单个JtaTransactionManager而不是几个JpaTransactionManager:分布式事务将涵盖两个实体管理器,它们也可以正常工作。