spring @transactional不使用@norepository层次结构

发布于 2025-01-25 02:07:44 字数 1269 浏览 5 评论 0原文

我有一个基本界面来收缩查询以进行自定义更新。这是在其他春季应用程序中使用的库,在某些环境中,我有一个次要的“ TransActionManager”,也有次要的“ EntityManager”。如果此次要交易管理器在春季上下文中存在,则我的存储库必须使用它。

因此,这是此基本存储库接口的代码:

@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)应用交易?

I have a base interface to contract a query for custom update. This is a library used in other spring applications, and in some enviroments I have a secondary "transactionManager" and also a secondary "entityManager". If this secondary transactionManager exists in spring context, my repository must to use it.

So here is the code of this base repository interface:

@NoRepository
interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {

   @Query("update ....")
   @Modifying
   void updateSomething();

}

I have then two other interfaces to be defined with conditionals:

@Repository("myEntityRepository")
@Transactional(transactionManager = "sharedTransactionManager")
@ConditionalOnBean(name = "sharedTransactionManager")
interface SharedMyEntityRepository extends MyEntityRepository {
}

@Repository("myEntityRepository")
@Transactional
@ConditionalOnMissingBean(name = "sharedTransactionManager")
interface DefaultMyEntityRepository extends MyEntityRepository {
}

But when I run the MyEntityRepository.updateSomething method, I'm getting this error:

org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress

How can I solve this? Why spring isn't applying the transaction based on the two @Repository (SharedMyEntityRepository or DefaultMyEntityRepository) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

诺曦 2025-02-01 02:07:44

由于@transactional无法向后工作,因此可以传播到子类,但不是相反的情况,您要么重新定义子类中的方法,要么在父类或方法本身上添加 @transactional。

Because the @Transactional doesn't work backwards ,it can be propagated to the subclasses but not the opposite,you either redefine the method in the subclass or add @Transactional on the parent class or method itself.

已下线请稍等 2025-02-01 02:07:44

经过一些测试,我使它起作用。

我只需要在基本接口方法中收缩 @transactional(没有任何交易操者)。之后,在儿童存储库中,我必须通过@transactional(transactionManager =“ sharedTransActionManager”)通过@transactional(TransActionManager =“ transactionManager =“ 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通过接口级别注释收缩。

After some tests, I got it working.

I just had to contract the @Transactional (without any transactionManager) in the base interface method. After that, at the child repository I had to contract the new transactionManager at my final interface via @Transactional(transactionManager = "sharedTransactionManager").

Here is the code:

@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 {
}

So, when the SharedMyEntityRepository.updateSomething runs, it starts a transaction using the sharedTransactionManager contracted via interface level annotation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文