Spring @Transactional 不适用于@NoRepository 层次结构
Spring @Transactional not working with @NoRepository hierarchy
我有一个基本接口来承包自定义更新的查询。这是一个在其他 spring 应用程序中使用的库,在某些环境中,我有一个辅助“transactionManager”和一个辅助“entityManager”。如果此辅助事务管理器存在于 spring 上下文中,我的存储库必须使用它。
下面是这个基本存储库接口的代码:
@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {
@Query("update ....")
@Modifying
void updateSomething();
}
我还有另外两个接口要用条件定义:
@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager")
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}
@Repository("myEntityRepository")
@Transactional
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}
但是当我 运行 MyEntityRepository.updateSomething
方法时,我收到了这个错误:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
我该如何解决这个问题?为什么 spring 不应用基于两个 @Repository(SharedMyEntityRepository 或 DefaultMyEntityRepository)的事务?
因为@Transactional 不能向后工作,它可以传播到 subclass 而不是相反,你要么重新定义 subclass 中的方法,要么添加 @Transactional在父 class 或方法本身上。
经过一些测试,我让它工作了。
我只需要在基本接口方法中收缩@Transactional(没有任何transactionManager)。之后,在子存储库中,我不得不通过 @Transactional(transactionManager = "sharedTransactionManager")
.
在我的最终界面上签订新的 transactionManager
代码如下:
@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {
@Transactional // this contracts the base method as transactional
@Query("update ....")
@Modifying
void updateSomething();
}
@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager") // override the transactionManager
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}
@Repository("myEntityRepository")
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}
因此,当 SharedMyEntityRepository.updateSomething
运行时,它使用通过接口级别注释约定的 sharedTransactionManager
启动事务。
我有一个基本接口来承包自定义更新的查询。这是一个在其他 spring 应用程序中使用的库,在某些环境中,我有一个辅助“transactionManager”和一个辅助“entityManager”。如果此辅助事务管理器存在于 spring 上下文中,我的存储库必须使用它。
下面是这个基本存储库接口的代码:
@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {
@Query("update ....")
@Modifying
void updateSomething();
}
我还有另外两个接口要用条件定义:
@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager")
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}
@Repository("myEntityRepository")
@Transactional
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}
但是当我 运行 MyEntityRepository.updateSomething
方法时,我收到了这个错误:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
我该如何解决这个问题?为什么 spring 不应用基于两个 @Repository(SharedMyEntityRepository 或 DefaultMyEntityRepository)的事务?
因为@Transactional 不能向后工作,它可以传播到 subclass 而不是相反,你要么重新定义 subclass 中的方法,要么添加 @Transactional在父 class 或方法本身上。
经过一些测试,我让它工作了。
我只需要在基本接口方法中收缩@Transactional(没有任何transactionManager)。之后,在子存储库中,我不得不通过 @Transactional(transactionManager = "sharedTransactionManager")
.
代码如下:
@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {
@Transactional // this contracts the base method as transactional
@Query("update ....")
@Modifying
void updateSomething();
}
@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager") // override the transactionManager
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}
@Repository("myEntityRepository")
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}
因此,当 SharedMyEntityRepository.updateSomething
运行时,它使用通过接口级别注释约定的 sharedTransactionManager
启动事务。