繁体   English   中英

在JPA / Hibernate中使用Spring定义的transactionManager

[英]Using Spring defined transactionManager in JPA/Hibernate

假设您将JPA与Spring一起使用,并将Hibernate作为JPA实现。 JPA事务模式是“ JTA”,因此您需要将容器transactionManager传递给Hibernate。 经典的答案是将hibernate.transaction.manager_lookup_class设置为服务器的匹配类。

但是,我认为这依赖于服务器特定的配置是很可惜的,因为您已经在Spring中使用<tx:jta-transaction-manager>找到了transactionManager。

有没有一种方法可以使该transactionManager使用类似的配置休眠

 <bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="persistence_unit_name"/>
  <property name="jpaVendorAdapter">
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
  </property>
  <property name="jpaProperties">
   <props>
    <prop key="hibernate.transaction.manager_lookup_class">
     org.hibernate.transaction.SunONETransactionManagerLookup
    </prop>
   </props>
  </property>
 </bean>

 <tx:jta-transaction-manager/>

目标是摆脱org.hibernate.transaction.SunONETransactionManagerLookup属性。 顺便说一句,我确实想到了两种不同的服务器实现。

编辑:没有事务管理器配置,创建EntityManagerFactory时休眠休眠:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:/C:/configuration/afoCuad-metier-ear/entitymanager-base-context.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: fr.tm.ima.cuad-afoCuad-metier-ejb-PU] Unable to build EntityManagerFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:529)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:495)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:656)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:629)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:338)
... 80 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: fr.tm.ima.cuad-afoCuad-metier-ejb-PU] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:901)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 93 more
Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:401)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:892)
... 98 more

首先-您真的需要JTA吗? 通常,spring + hibernate不需要它。 您可以使用简单的JpaTransactionManager / HibernateTransactionManager

如果您确实需要JTA,则需要一个JTA提供程序。 如果未在应用程序服务器中运行,请检查此问题以了解如何在servlet容器中使用JTA。 (也看看这个问题

最后, 休眠文档为容器管理的事务指定以下内容:

声明式事务划分是EJB的标准功能,也称为容器管理的事务(CMT)。 在EJB 2.x中,您将使用XML部署描述符来创建事务程序集。 在EJB 3.x中,您可以直接在源代码中使用JDK 5.0注释元数据,这种方法不那么冗长。 要在Hibernate配置中为EJB启用CMT事务划分,请执行以下操作:

  • hibernate.transaction.manager_lookup_class设置为您的JEE容器的查找策略
  • hibernate.transaction.factory_class设置为org.hibernate.transaction.CMTTransactionFactory

第二点也许是您错过的东西?

该文档除此之外(下一部分)说的是,如果您要进行声明式事务处理,那么休眠就不是您应该关注的地方。 您需要创建一个拦截器。 这正是春季交易经理的身份。 鉴于您的技术堆栈(春季),那将是我的选择。

如果您不希望依赖单个JTA提供程序,则进行两个构建。 例如,maven具有“ maven配置文件”,该文件允许针对不同的环境进行构建。

不幸的是,如果像许多其他JBoss产品一样看待Hibernate API,它们就有一个通常称为Configuration的类来容纳大部分(如果不是全部)主要的config东西。 不幸的是,他们(JBoss)似乎喜欢使用“字符串”作为参数和类来定位实例。 几乎总是不可能简单地设置实际的预制准备就绪设置。

出于您提到的相同原因,我将尝试类似于以下内容的操作。

  • 创建一个TransactionManagerLookup的实现
  • 包括一个使用TM的设置器,并设置线程局部变量+实例。
  • 在传递给配置的属性内传递TML的名称。
  • 当您的TML启动时,将线程局部变量复制到您的实例fie.d。
  • 一切完成后,清除threadlocal。

我最近一直在用JPA / Grails做一些事情,我使用的配置遵循以下原则:

这有帮助吗?

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

<bean id="entityManagerFactory" class="org.hibernate.ejb.EntityManagerFactoryImpl">
 <constructor-arg index="0" ref="sessionFactory"/>
 <constructor-arg index="1">
   <bean id="javax.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
 </constructor-arg>
 <constructor-arg index="2" value="true"/>
 <constructor-arg index="3"><null/></constructor-arg>
</bean>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM