Spring JPA 存储库事务性
Posted
技术标签:
【中文标题】Spring JPA 存储库事务性【英文标题】:Spring JPA repository transactionality 【发布时间】:2017-02-11 03:06:23 【问题描述】:关于 的 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”异常。
好的,我可以通过将服务 or deleteByEmail(..) 方法标记为事务性来解决它,但我就是不明白为什么它现在崩溃了。 Spring 文档明确指出“存储库实例上的 CRUD 方法默认情况下是事务性的。”(http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这个不是......所以这个声明仅与 @987654324 的成员有关@?
ps:那是 Spring Data 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
如果您想了解有关它如何实现的更多信息,请查看默认的 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)
【讨论】:
在 spring-data-jpa:2.0.9 中,JpaRepository
或其祖先的源代码中没有 @Transactional
注释 - 默认事务性似乎在运行时应用。另请注意,如果您将@Transactional( ... custom properties ... )
放在您的存储库接口上,它将适用于在您的接口和子接口中声明的所有方法——但不适用于在父接口 (JpaRepository
) 中声明的任何方法,除非您重新声明它们.
@AndrewSpencer @Transactional
注释默认应用JpaRepository
/ CrudRepository
实现:SimpleJpaRepository
看这里:github.com/spring-projects/spring-data-jpa/blob/master/src/main/… 我想你会在那里找到所有答案:)
感谢您的更正 - 这不是运行时魔法,只是注释的实现类。不过,我关于覆盖的评论仍然是准确的。以上是关于Spring JPA 存储库事务性的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA + Hibernate 将方法标记为事务
Spring 4.3.0.RELEASE + Hibernate 5.2.0.Final + JPA 存储库
Spring JPA Repository findAll 在 JUnit 测试中不返回任何数据