11

Spring で JPA を使用し、JPA 実装として Hibernate を使用するとします。JPA トランザクション モードは「JTA」であるため、コンテナーの transactionManager を Hibernate に渡す必要があります。古典的な答えはhibernate.transaction.manager_lookup_class、サーバーに一致するクラスに設定することです。

ただし、これがサーバー固有の構成に依存するのは残念だと思います。Spring で<tx:jta-transaction-manager>.

この transactionManager を次のような構成で Hibernate に与える方法はありますか

 <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物件を手放すのが目的です。ところで、私は本当に 2 つの異なるサーバーの実装を考えています。

EDIT : トランザクション マネージャーの構成がないと、Hibernate は 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
4

3 に答える 3

7

まず第一に -本当にJTA が必要ですか? 通常、春と休止状態では必要ありません。シンプルなJpaTransactionManager/を使用できますHibernateTransactionManager

本当に JTA が必要な場合は、JTA プロバイダーが必要になります。アプリケーション サーバーで実行されていない場合は、サーブレット コンテナーで JTA を使用する方法について、この質問を確認してください。(この質問も見てください)

最後に、休止状態のドキュメントでは、コンテナー管理のトランザクションについて次のように指定されています。

宣言型トランザクション境界設定は、コンテナ管理トランザクション (CMT) とも呼ばれる EJB の標準機能です。EJB 2.x では、XML デプロイメント記述子を使用してトランザクション アセンブリを作成します。EJB 3.x では、JDK 5.0 アノテーション メタデータをソース コードで直接使用できます。Hibernate 構成で EJB の CMT トランザクション境界設定を有効にするには:

  • hibernate.transaction.manager_lookup_classJEE コンテナーのルックアップ戦略に設定する
  • hibernate.transaction.factory_classに設定org.hibernate.transaction.CMTTransactionFactory

2番目のポイントは、おそらくあなたが見逃したものですか?

それに加えてドキュメントに記載されていること (次のセクション) は、宣言型トランザクションが必要な場合は、休止状態は注目すべき場所ではないということです。インターセプターを作成する必要があります。それがまさに春のトランザクションマネージャーです。そして、あなたの技術スタック (Spring) を考えると、それが私の選択です。

単一の JTA プロバイダーに依存したくない場合は、2 つのビルドを作成します。たとえば、maven には「maven プロファイル」があり、さまざまな環境のビルドを作成できます。

于 2010-12-10T08:15:03.780 に答える
1

残念ながら、他の多くのJBoss製品と同様にHibernate APIを見ると、すべてではないにしてもほとんどの主要な構成要素を保持するために、通常は構成と呼ばれるクラスがあります。残念ながら、彼ら(JBoss)は、インスタンスを見つけるためのパラメーターとクラスの「文字列」を保持することを好むようです。ほとんどの場合、実際の既製のセットアップを簡単に設定することは不可能です。

あなたが言及しているのとまったく同じ理由で、私は次のようなことを試みようとしています。

  • TransactionManagerLookupの実装を作成します
  • TMを受け取り、スレッドローカル変数+インスタンスを設定するセッターを含めます。
  • 構成に渡すプロパティ内にTMLの名前を渡します。
  • TMLが起動したら、スレッドローカル変数をインスタンスfie.dにコピーします。
  • すべてが完了したら、threadlocalをクリアします。
于 2011-01-30T23:54:56.870 に答える
0

私は最近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>
于 2010-12-09T15:54:27.677 に答える