java - Spring JPA 存储库事务性

标签 java jpa spring-data spring-transactions

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

userRegistrationRepository.deleteByEmail(email);

它被定义为

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

    UserRegistration findByEmail(String email);

    void deleteByEmail(String email);

}

问题是它失败并显示“没有 EntityManager 具有可用于当前线程的实际事务 - 无法可靠地处理‘删除’调用;嵌套异常是 javax.persistence.TransactionRequiredException”异常。

好的,我可以通过将服务 deleteByEmail(..) 方法标记为事务性来解决它,但我只是不明白为什么它现在崩溃了。 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);

}

您还应该了解标记存储库接口(interface)方法而不是服务方法的后果。如果您使用默认事务传播配置 (Propagation.REQUIRED),则:

The transaction configuration at the repositories will be neglected then as the outer transaction configuration determines the actual one used.

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

关于java - Spring JPA 存储库事务性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39827054/

相关文章:

在 java servlet 中找不到 javax.ws

java - 如何在 Spring JDBC 中创建对象之间的关系?

java - tomcat 7 + jersey + hibernate 4.5.1 - NameNotFoundException - 尝试了一切

java - 如何在 JPAQuery 中使用 INNER JOIN?

java - 从Java访问文件名中带空格的文件

java - sonarqube 进程 [es] 无法在 Ubuntu 上启动

java - Entitymanager.flush() VS EntityManager.getTransaction().commit - 我应该更喜欢什么?

java - 持久化时间戳类型只有日期没有时间

java - 在不同的 Spring 数据存储库中使用相同的实体类

java - Spring数据设置实体