关于Spring JPA repositories的事务性问题,我有一个快速的问题。
我有一个未标记为事务性的服务,调用了Spring JPA repository方法。
userRegistrationRepository.deleteByEmail(email);
并且它被定义为
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
void deleteByEmail(String email);
}
问题在于它出现了 "No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call; nested exception is javax.persistence.TransactionRequiredException" 异常。
我可以通过将服务 或 deleteByEmail(..) 方法标记为事务来解决它,但我就是不明白为什么现在会崩溃。Spring 文档明确指出 "CRUD methods on repository instances are transactional by default." (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这个问题却不是...那么这个声明是否只与 CrudRepository
的成员相关呢?
ps:这是针对 Spring Data JPA 1.9.4 的。
JpaRepository
及其祖先源代码中没有@Transactional
注解 - 默认的事务处理似乎是在运行时应用的。另外,请注意,如果您在存储库接口上放置了@Transactional( ... 自定义属性 ... )
,它将适用于在接口中声明的所有方法以及子接口中声明的所有方法--但不适用于任何在父接口(JpaRepository
)中声明的方法,除非你重新声明它们。 - Andrew Spencer@Transactional
注释被应用于默认的JpaRepository
/CrudRepository
实现:SimpleJpaRepository
。请参考此处链接查看详情:https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java ,您将在该链接中找到所有答案 :) - Maciej Marczuk