Tomcat内でSpringでJPAを使用しようとしていて、トランザクションが期待通りに開始されないという問題があります。TomcatでSpringとJPAを使用してトランザクションを開始しない
私は、Hibernate 3.6.9.Final、Spring 3.0.5.RELEASEを使用しており、Tomcat 6.0.30で動作しています。
私は、エンティティとデータアクセスオブジェクトを含む別個のデータアクセス用のjarファイルを持っています。このjarには、次の内容のMETA-INF/persistence.xmlファイルが含まれています。
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="osPU">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
</persistence>
これはわかりますが、これは非常に単純で、実際にはJPAがJPAエンティティを含むjarであることを知るためのマーカーです。
エンティティは、春のbeansファイルの次の設定に基づいてOKです。
<tx:annotation-driven />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${database.dialect}</prop>
<prop key="hibernate.show_sql">${database.show.sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
私はDAOのメソッドへのすべての発信者が適切にトランザクションを作成することを確認するため、私は
@Transactional(propagation=Propagation.MANDATORY)
と私のDAOをマークしました。
私はDAOにはから呼び出されるすべてのメソッドに
@Transactional
を追加しました。
この結果、例外が発生します。
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
私はDAO @Transactional注釈から伝播= Propagation.MANDATORYを削除した場合のEntityManagerが変更をフラッシュしようとしたとき、私はエラーを取得します。
すべてのアイデアをいただければ幸いです。
EDIT私はスタック内のすべてのレベルでGenericsを使用しています。コントローラ、サービス、およびDAO。 Springがメソッド呼び出しをインターセプトしてトランザクションでラップすることができないため、これが問題を引き起こしているかどうかは不明です。
public abstract class AbstractEavDefinitionController<DTO> implements EAVDefinitionOperations<DTO> {
private EavDefinitionService<DTO> eavDefinitionService;
private Validator<DTO> validator;
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ServiceResult<Long> save(@RequestBody DTO dto) {
ValidationResult<DTO> validationResult = validator.validate(dto);
if (validationResult.isValid()) {
Long result = eavDefinitionService.save(dto);
return new SimpleServiceResult<Long>(result);
}
return new SimpleServiceResult<Long>(validationResult);
}
}
バリやアクティブなトランザクションを持っている必要があり、サービス利用のDAO両方:ここ
詳細は、コントローラのコードです。バリデータ呼び出しは期待どおりに動作し、DB呼び出しを行うことができます。サービスへの呼び出しがスローされます
javax.persistence.TransactionRequiredException: no transaction is in progress
私が理解できないのは、DAOへの呼び出しが成功したが、次の呼び出しが失敗することです。トランザクションを使用するときにコントローラコール内で開くことができるトランザクションの数には制限がありますか?
注釈を付けている方法を? – mrembisz
コントローラからDAOへのすべての呼び出しは、スプリングマネージドBeanを経由します。それはあなたが意味することですか? –
いいえ、トランザクションコントローラメソッドがどのように呼び出されるかが重要です。コントローラメソッド呼び出しがプロキシを経由する場合にのみ、必要なトランザクションが開始されます。 – mrembisz