Grails 为什么';我的GORM对象是否保存到数据库?
考虑以下代码:Grails 为什么';我的GORM对象是否保存到数据库?,grails,transactions,gorm,grails-2.0,Grails,Transactions,Gorm,Grails 2.0,考虑以下代码: if (!serpKeyword) { serpKeyword = new SerpKeyword( keyword: searchKeyword, geoKeyword: geoKeyword, concatenation: concatenation, locale: locale ) serpKeyword.save(flush: true, failOn
if (!serpKeyword) {
serpKeyword = new SerpKeyword(
keyword: searchKeyword,
geoKeyword: geoKeyword,
concatenation: concatenation,
locale: locale
)
serpKeyword.save(flush: true, failOnError: true)
}
serpService.submitKeyword(serpKeyword, false)
以下是submitKeyword方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
boolean submitKeyword(keywordToSubmit, boolean reset) {
def keyword = SerpKeyword.get(keywordToSubmit.id)
调用serpKeyword.save
时不会引发错误,但进入submitKeyword
方法时,serpKeyword.get(keywordToSubmit.id)
返回null。是什么阻止了这一点
编辑
将需要\u NEW
更改为REQUIRED
似乎可以奏效。以下是我认为正在发生的事情
调用serpService.submitKeyword
的代码位于服务方法中。据我所知,服务方法的默认传播策略为REQUIRED
。由于所有这些数据库写入都发生在事务的上下文中,因此写入会在数据库中排队,但在事务完成之前,不会对数据库实际执行,根据:
请注意,刷新与提交事务不同。如果
您的操作是在事务上下文中执行的,例如刷新
将执行SQL更新,但数据库将在其
事务队列,仅在事务
承诺
我们在事务实际完成之前调用
serpService.submitKeyword
。该方法启动一个全新的事务,其中我们的serpKeyword
不可用。将其更改为REQUIRED
很有效,因为我们现在在父事务的上下文中操作。我认为堆栈的某些部分是懒惰的。我在Hibernate中遇到过这种行为,如果您使用的是Hibernate的话。我不确定这是否是一个批准的操作,但您可以在调用submitKeyword
之前清除会话,如下所示:
long keywordId = serpKeyword.id
SerpKeyword.withSession{it.clear()}
serpService.submitKeyword(keywordId, false)
然后将方法更改为:
@Transactional(propagation = Propagation.REQUIRES_NEW)
boolean submitKeyword(keywordId, boolean reset) {
def keyword = SerpKeyword.get(keywordId)
然后我打赌
.get()
会起作用。如果会话中有其他需要的对象。您需要通过存储它们的id和.get()
来将它们取出。可能是您的某些域字段为空或无效。尝试将所有域字段设置为一些有效值。@ToddMurray:我已经设置了FailOneError
属性;如果我的记录无效,不会抛出异常吗?还值得注意的是:如果我将SerpKeyword
的创建包装在一个with newtransaction
块中,它会保存到数据库中,但随后可能由于锁定问题而无法更新记录。您确定您的代码通过SerpKeyword.save()
?如果在调试中检查传递给服务的实例,可以看到id不为null?在保存之前是否尝试过serpKeyword.validate()
?@sérgioMichels:是的,传递给服务的对象的id不为null。请查看我的编辑。我的发现和你的建议一致吗?