Spring JUnitテストで@Transactionalアノテーションが存在し、JPA2エンティティを永続/マージするときにカスケードするリンクがあるようです。@トランザクションとカスケードのリンクは何ですか?
私は現時点での設定は行っていませんが、ここに誰かにベルが鳴るのでしょうか?
3つのレベルでJPAエンティティの単純なケースを想定:エンティティAは、クラスBのエンティティを参照すると、クラスBのインスタンスは、クラスC.
Aのインスタンス参照 - > B - > Cを
クラスAはBをALLにカスケードします.BはALLをCにカスケードします。クラスCには@PrePersistと@PreUpdateでアノテーションされたイベントリスナメソッドがあります。カスケード接続を証明するメッセージをログに記録します。
さて、いくつかの方法で、エンティティCを変更し、マージしたり、最終的に保持されますA.論理エンティティCのインスタンスを持続またはもマージするエンティティマネージャをお願いします。カスケーディングはクラスAからBからCにALLに設定されています。
Springユニットテストに@Transactionalアノテーションが付いていないと、クラスCのイベントリスナーメソッドからのログメッセージがメッセージを出力します。 OK。
しかし、が@Transactionalで注釈されたの場合、メッセージは一切表示されません。そして実際には、クラスCのデータベースには何もコミットされていません。クラスAの場合のみです。したがって、カスケード処理ではAからCへの変換はできませんでした。
注釈を削除すると問題が解決します。
誰か手掛かりがありますか? :-)論理的には、トランザクションとカスケードは完全に別々の2つの問題だと私は考えます。
典型的なテストケースの設定:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/test-beans.xml")
@TransactionConfiguration
@Transactional
public class MyUnitTest {
...
@Test
public void testSomething() {}
...
}
Spring XML構成ファイルの抽出 - そこに派手な何も私は思う...
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="com.foo.bar" />
<bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="/META-INF/persistence.xml"/>
<property name="persistenceUnitName" value="bar" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
エキスのpersistence.xml
から<persistence-unit name="bar" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/bar" />
<property name="hibernate.connection.username" value="bar" />
<property name="hibernate.connection.password" value="pwd" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
図書館
- 春3.0.6 ORM/CONTEXT/TEST
- 休止3.6.7.Final
- のJUnit 4.9
- JPA2
カスケードとトランザクションは完全に分離した問題ではありません。カスケードとは、ある種のSQLをデータベースに送信することを意味します。これは、トランザクションをコミットするときに発生します。 entityManager.getTransaction.begin()と.commit()を使用して単体テストでトランザクションをプログラム的に開始したり終了したりしてください。この非標準的なすべてのジャンボを使用しないでください。 JPA2には、トランザクションがアプリケーションサーバー/ ejbコンテナの内部と外部でどのように動作するかについての非常に明確なドキュメントがあります。 –
私の知る限りでは、カスケードは持続性プロバイダ(つまり、休止状態)によって強制されます。取引の実行方法にかかわらず。だから私の質問はまだ立っている:トランザクションが存在するときにプロバイダがカスケードしないのはなぜですか? –
あなたは試してみることが2つあります:1. true をあなたの休止状態の設定とデバッグに追加してSQLログを有効にして、両方の状況(そしていつ) 。その後、Spring @ Transactionと手動でトランザクションを停止し、トランザクションを停止して同じことが起きているかどうかを確認します。 –