关于Spring JPA存储库事务性的1个快速问题。 我有一个未标记为事务的服务,并调用Spring JPA存储库方法
userRegistrationRepository.deleteByEmail(email);
它被定义为
@Repository
public interface UserRegistrationRepository extends JpaRepository<UserRegistration, Long> {
UserRegistration findByEmail(String email);
void deleteByEmail(String email);
}
问题在于它失败了&#34; 没有EntityManager,当前线程可以使用实际交易 - 无法可靠地处理&#39;删除&#39;呼叫;嵌套异常是javax.persistence.TransactionRequiredException &#34;异常。
好的,我可以通过将服务或 deleteByEmail(..)方法标记为事务来解决此问题,但我无法理解为什么它现在崩溃了。 Spring文档明确指出,默认情况下,存储库实例上的&#34; CRUD方法是事务性的。&#34; (http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions),但显然这个不是......那么这个陈述只与CrudRepository
的成员有关吗?
ps:Spring Data JPA 1.9.4的那个
答案 0 :(得分:23)
你是对的。默认情况下,只有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
(您可能正在使用):
有趣的路线在这里:
@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) {