Spring 和 JTA 错误

Spring and JTA error

我正在尝试使用 Atomikos 将 Spring JPA/Hibernate 项目与 JTA 集成。

我正在开发一个小示例,您可以找到它 in this repository

您可以在那里看到所有内容(persistence.xml、applicationContext.xml 等)。但我将在这里展示该文件的片段:

persistence.xml:

<persistence-unit name="presistence-unit" transaction-type="JTA"> <!--  transaction-type="RESOURCE_LOCAL"> -->
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/ct</jta-data-source>
    <class>org.sergio.jtaSpringProject.entities.Transfer</class>
    <class>org.sergio.jtaSpringProject.entities.Client</class>
    <properties>
       <property name="hibernate.hbm2ddl.auto" value="update" />
       <property name="hibernate.show_sql" value="false" />
       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
       <property name="hibernate.connection.autocommit" value="false" />
       <property name="hibernate.transaction.factory_class" value="org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory" />
       <!-- <property name="hibernate.transaction.factory_class" value="com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory" /> -->
       <property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" />
     </properties>
</persistence-unit>

applicationContext.xml:

<!-- Create proxy instances of Repository interfaces -->
<jpa:repositories base-package="org.sergio.jtaSpringProject.repositories"/>

<tx:annotation-driven  transaction-manager="transactionManager"/>

<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
    <property name="uniqueResourceName">
        <value>XADBMS</value>
    </property>
    <property name="xaDataSourceClassName">
        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
    </property>
    <property name="xaProperties">
       <props>
            <prop key="URL">jdbc:mysql://localhost:3306/ct</prop>
            <prop key="user">root</prop>
            <prop key="password">root</prop>
       </props>
    </property>
    <property name="maxPoolSize" value="3" />
    <property name="minPoolSize" value="1" />
</bean>

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <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="true" />
            <property name="database" value="MYSQL" />
        </bean>
      </property>
      <property name="persistenceXmlLocation">
        <value>persistence.xml</value>
      </property>
    <property name="persistenceUnitName" value="presistence-unit" />
 </bean>

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
    <property name="forceShutdown" value="false" />
</bean>

<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
    <property name="transactionTimeout" value="300" />
</bean>

<bean id="transactionManager"
    class="org.springframework.transaction.jta.JtaTransactionManager"
    depends-on="atomikosTransactionManager,atomikosUserTransaction">
    <property name="transactionManager" ref="atomikosTransactionManager" />
    <property name="userTransaction" ref="atomikosUserTransaction" />
    <property name="allowCustomIsolationLevels" value="true" />
</bean>

当我 运行 这个项目时,我得到下一个错误:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRepository': Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at org.sergio.jtaSpringProject.App.main(App.java:30)
Caused by: java.lang.NullPointerException
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76)
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118)
    at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:210)
    at org.hibernate.jpa.internal.EntityManagerImpl.<init>(EntityManagerImpl.java:91)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:345)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541)
    at com.sun.proxy.$Proxy17.createEntityManager(Unknown Source)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:287)
    at com.sun.proxy.$Proxy25.getDelegate(Unknown Source)
    at org.springframework.data.jpa.provider.JpaClassUtils.isEntityManagerOfType(JpaClassUtils.java:46)
    at org.springframework.data.jpa.provider.PersistenceProvider.fromEntityManager(PersistenceProvider.java:296)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.<init>(JpaRepositoryFactory.java:57)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.createRepositoryFactory(JpaRepositoryFactoryBean.java:79)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.doCreateRepositoryFactory(JpaRepositoryFactoryBean.java:69)
    at org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport.createRepositoryFactory(TransactionalRepositoryFactoryBeanSupport.java:72)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:216)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 12 more

为什么不能 Spring 实例化两个存储库?

我修好了!

正确的配置在https://github.com/serrodcal/spring-jta-atomikos

基本上,问题是:

<jpa:repositories base-package="org.sergio.jtaSpringProject.repositories"/>

Jpa 存储库需要知道 entityManagerFactory 和 transactionManager。我解决了这个问题:

<jpa:repositories base-package="org.sergio.jtaSpringProject.repositories"
                  entity-manager-factory-ref="entityManagerFactory"
                  transaction-manager-ref="transactionManager"/>