web-dev-qa-db-ja.com

Spring JPAリポジトリのトランザクション性

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の場合

18
FlasH from Ru

あなたが正しいです。 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(おそらく使用している)をご覧ください。

https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/Java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.Java

興味深い行は次のとおりです。

@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) {
27
Maciej Marczuk