Java 带Spring数据的JPA

Java 带Spring数据的JPA,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,我是Java新手,我需要创建一个控制台应用程序,该应用程序将连接4个数据库(access、vfp、mysql和sqlserver) 我从hibernate.cfg.xml文件开始,并设法对它们进行配置,每个数据库一个。然后我意识到jpa是一个更好的解决方案。因此,我将所有hibernate文件更改为一个带有4个持久性单元的persistence.xml文件 数据库运行良好,但要使用它们,我必须创建大量代码。这是一个例子: EntityManagerFactory dbPersistence =

我是Java新手,我需要创建一个控制台应用程序,该应用程序将连接4个数据库(access、vfp、mysql和sqlserver)

我从hibernate.cfg.xml文件开始,并设法对它们进行配置,每个数据库一个。然后我意识到jpa是一个更好的解决方案。因此,我将所有hibernate文件更改为一个带有4个持久性单元的persistence.xml文件

数据库运行良好,但要使用它们,我必须创建大量代码。这是一个例子:

EntityManagerFactory dbPersistence = 
   Persistence.createEntityManagerFactory("oneOfMyDatabases");

EntityManager em = dbPersistence.createEntityManager();

Query query = em.createQuery("from ProductEntity").setMaxResults(10);

for (Object o : query.getResultList()) {
    ProductEntity c = (ProductEntity) o;
    System.out.println("Product " + c.getName());
}

cgPersistence.close();
我需要用其他数据库的数据更新其中一个数据库

像这样创建所有代码是一件痛苦的事情,所以我考虑过创建存储库,但我不知道如何使用不同的EntityManager为每个数据库创建它们

我试图向管理人员注入GoogleGuice,但没有成功,但我无法处理如何关闭或在何处关闭持久性连接

最后,我找到了Spring数据,它似乎是我所需要的,但我真的不知道如何使用它

我需要一些指南来让它工作,因为我已经阅读了大量的教程,其中每一个看起来都不一样: ·我可以使用相同的persistence.xml还是需要另一个配置文件?我已经看到Spring数据具有jpa兼容性,但我不确定它是如何工作的。 ·Spring上下文是Spring框架的IOC容器吗?我需要它来处理Spring数据吗? ·我还需要什么


提前感谢

每个数据库将由不同的数据源表示。对于每个数据源,您都需要一个不同的会话工厂/实体管理器工厂

如果要在单个事务中保存多个数据源,则需要XA事务,因此需要Java EE或独立事务管理器,如Bitronix或Atomikos

您有4个不同的实体管理器工厂,您还需要为每一个工厂指定特定的存储库:

<jpa:repositories base-package="your.company.project.repository.access" entity-manager-factory-ref="accessEntityManagerFactory"/>

<jpa:repositories base-package="your.company.project.repository.sqlserver" entity-manager-factory-ref="sqlserverEntityManagerFactory"/>

这样,您的应用程序就不必关心它使用哪个存储库

JpaTransactionManager需要一个entityManagerFactory,但由于您有4个,您可能最终会创建其中的一个,我认为这是不可取的

最好改用JTA:

<!-- 1. You define the Bitronix config ->
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
    <property name="serverId" value="spring-btm"/>
    <property name="warnAboutZeroResourceTransaction" value="true"/>
    <property name="logPart1Filename" value="${btm.config.logpart1filename}"/>
    <property name="logPart2Filename" value="${btm.config.logpart2filename}"/>
    <property name="journal" value="${btm.config.journal:disk}"/>
</bean>

<!-- 2. You define all your data sources ->
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init"
      destroy-method="close">
    <property name="className" value="${jdbc.driverClassName}"/>
    <property name="uniqueName" value="dataSource"/>
    <property name="minPoolSize" value="0"/>
    <property name="maxPoolSize" value="5"/>
    <property name="allowLocalTransactions" value="false"/>
    <property name="driverProperties">
        <props>
            <prop key="user">${jdbc.username}</prop>
            <prop key="password">${jdbc.password}</prop>
            <prop key="url">${jdbc.url}</prop>
        </props>
    </property>
</bean>

<!-- 3. For each data source you create a new  persistenceUnitManager and you give its own specific persistence.xml ->
<bean id="persistenceUnitManager" depends-on="transactionManager"
      class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"/>
    <property name="defaultDataSource" ref="dataSource"/>
    <property name="dataSourceLookup">
        <bean class="org.springframework.jdbc.datasource.lookup.BeanFactoryDataSourceLookup"/>
    </property>
</bean>

<!-- JpaDialect must be configured for transactionManager to make JPA and JDBC share transactions -->
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

<!-- 4. For each data source you create a new entityManagerFactory ->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="persistenceUnitManager" ref="persistenceUnitManager"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

<!-- 5. You have only one JTA transaction manager ->
<bean id="jtaTransactionManager" factory-method="getTransactionManager"
      class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig, dataSource"
      destroy-method="shutdown"/>

<!-- 6. You have only one Spring transaction manager abstraction layer ->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="jtaTransactionManager"/>
    <property name="userTransaction" ref="jtaTransactionManager"/>
</bean>


如果所有数据库的模式都相同,那么最好的方法是使用hibernate,因为hibernate提供了多个数据库之间的可移植性。创建hbm文件和pojo类后,只需更改方言和数据源


transactionmanager支持可以由spring提供。

我认为我已经完成了所有工作,除了这个错误“没有定义名为“transactionmanager”的bean”。我可以对所有内容使用相同的事务管理器,还是必须为每个数据源定义一个不同的TM?这意味着我不需要处理事务?我必须删除带有用户、密码和url的消息,因为我得到每个属性的消息:无可写属性url |用户|密码。删除driverProperties后,我出现了以下错误:java.lang.ClassCastException:jstels.jdbc.dbf.DBFDriver2无法转换为javax.sql.XADataSource。可能驱动程序不兼容?大多数DB驱动程序都支持XA,对于特定的驱动程序,您可以使用LRC Bitronix XA包装器,允许您在全局Tx中最多登记一个非XA数据源。如果这证明对您当前的问题来说工作量过大,您可以尝试使用4个JPA事务管理器,看看它是如何工作的。您需要4个DS和4个EMF工厂。Spring TM只处理事务边界,Bitronix是XA TM实现。如果所有数据库中都有相同的模式,我建议您检查一下。如果没有,您需要创建4个数据源和4个实体管理器,正如@vlad mihalcea所指出的那样