春季 JPA 存储库事务性

2022-09-01 08:40:14

1 个关于春季 JPA 存储库事务性的快速问题。我有一个未标记为事务性的服务,并调用Spring JPA存储库方法

userRegistrationRepository.deleteByEmail(email);

它被定义为

@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {

    UserRegistration findByEmail(String email);

    void deleteByEmail(String email);

}

问题是它失败,“没有实体管理器与实际事务可用于当前线程 - 无法可靠地处理'删除'调用;嵌套异常是 javax.persistence.TransactionRequiredException“ exception。

好吧,我可以通过将服务deleteByEmail(..)方法标记为事务性来解决它,但我只是不明白为什么它现在崩溃了。Spring文档明确指出“默认情况下,存储库实例上的CRUD方法是事务性的。http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这个不是...那么,此语句是否仅与 的成员相关?CrudRepository

ps:那是春季数据 JPA 1.9.4


答案 1

你是对的。默认情况下,只有 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

如果您想了解有关其实现方式的更多信息,请查看默认/实现 - (您可能正在使用):CrudRepositoryJpaRepositorySimpleJpaRepository

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) {

答案 2

推荐