Spring JPAリポジトリのトランザクション性に関する1つの簡単な質問。トランザクションとしてマークされておらず、Spring JPAリポジトリメソッドを呼び出すサービスがあります
userRegistrationRepository.deleteByEmail(email);
そして、それは
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
void deleteByEmail(String email);
}
問題は、「現在のスレッドで実際のトランザクションを使用できるEntityManagerがありません。'remove '呼び出しを確実に処理できません。ネストされた例外はjavax.persistence.TransactionRequiredException」例外です。
OK、サービスordeleteByEmail(..)メソッドをトランザクションとしてマークすることで解決できます。しかし、なぜ今クラッシュするのか理解できません。 Springのドキュメントでは、「リポジトリインスタンスのCRUDメソッドはデフォルトでトランザクション対応です。」( http://docs.spring.io/spring-data/jpa/ docs/current/reference/html /#transactions )しかし、明らかにこれはそうではありません...だから、このステートメントはCrudRepository
のメンバーのみに関連していますか?
pS:Spring Data JPA 1.9.4の場合
あなたが正しいです。 CRUDメソッド(CrudRepository
メソッド)のみがデフォルトでトランザクションとしてマークされます。カスタムクエリメソッドを使用している場合は、@Transactional
アノテーションで明示的にマークする必要があります。
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
@Transactional
void deleteByEmail(String email);
}
また、サービスメソッドの代わりにリポジトリインターフェイスメソッドをマークした結果についても注意する必要があります。デフォルトのトランザクション伝播構成(Propagation.REQUIRED
)を使用している場合:
リポジトリでのトランザクション設定は、外部トランザクション設定が実際に使用されるものを決定するため、無視されます。
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
実装方法の詳細については、デフォルトのCrudRepository
/JpaRepository
実装-SimpleJpaRepository
(おそらく使用している)をご覧ください。
興味深い行は次のとおりです。
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
ここにいくつかのトランザクションメソッドがあります。
@Transactional
public void deleteById(ID id) {
@Transactional
public <S extends T> S save(S entity) {