【问题标题】:Grails: issue when calling a service method from other service methodGrails:从其他服务方法调用服务方法时的问题
【发布时间】:2011-07-02 10:03:54
【问题描述】:

我在同一个服务类中有这两种方法:

boolean meth1(DomClass dom1) { //参数是域类DomClass的一个实例 ... meth2(dom1) ... dom1.delete(刷新:真) ... 返回真 } 布尔方法 2(DomClass dom1){ ... dom1.changeSomeProperty dom1.save(刷新:真) 返回真 }

问题在于,在调用dom1.delete(flush: true) 的行上,程序会因deleted object would be re-saved by cascade (remove deleted object from associations) 而崩溃。

现在,我不太了解 Hibernate,但我的猜测是,这两种方法都在创建一个新事务,meth1 有第一个事务,meth2 有第二个事务。事实上,如果我删除 dom1.save 一切正常。

现在,我的问题是:我可以让 meth1 包含来自 meth2 的所有代码,但这意味着我会重复很多代码(在我的真实示例中,我想在很多地方重用一些逻辑)。如何通过使所有服务方法堆栈在同一个事务中运行来重用一种方法上的代码(如果这确实是问题,否则:“问题是什么?”)

【问题讨论】:

  • 让我们查看 dom1 的域映射以及引用它的任何其他类。

标签: hibernate grails transactions grails-orm


【解决方案1】:

当 ClassA 的实例被 ClassB 的实例引用时会发生该错误,并且 B 的级联设置会导致 A 的实例被保存,并且您删除 A 的实例。修复很简单,具体做什么异常表示并从引用它的任何域类中删除 classA。

所以在你的情况下 dom1 被休眠会话中的另一个对象引用。您需要通过您的域模型并找出关联是什么,然后从另一个实例中删除 dom1。

删除保存调用使代码看起来可以工作的原因是,如果没有保存,您可能没有保存正在访问 dom1 并导致错误开始的另一个实例。如果没有保存该实例,就没有级联。

除非您自己是配置事务,否则在第一个服务方法调用中发生的所有服务方法调用都应该使用相同的事务。所有服务方法都参与同一个事务,除非您明确编写代码不这样做。您发布的...中可能有一些内容。

【讨论】:

  • 好的,但在那之后,我得到一个“行已被另一个事务更新或删除(或未保存的值映射不正确)” - (事务=false它会抛出相同的异常,但它保存好的)。那么,再次关于服务中的事务:如果我直接从 meth1() 调用 meth2(),那会进行 2 次事务吗?
  • @cripox 之后呢?我更新了我的答案...简短的回答是否定的,所有服务方法调用应该只有 1 个事务,除非您明确创建事务。
  • @hygotcodes - 我的意思是 - 在我解决了参考问题之后。那只是一个副作用。 - 我明天会挖更多。感谢您的回答。
  • @cripox 您将需要发布您的域类(只是引用其他类的部分)和更多服务代码供我帮助......
  • 我更好地阅读了规范并找出了域类的问题所在。感谢您回答有关交易的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
相关资源
最近更新 更多