在将项目从1.3.7迁移到2.4.1时,我偶然发现了几件事。其中之一是,我发现obj.delete()
在2.4.1中不再存在,除非我使用obj.delete(flush:true)
。
当我读到Grails UserGuide时,它说'...实例被立即删除'我理解flush:true
参数是强制持久化对象的选项当hibernate认为它没问题时,立即而不是“让它坚持下去”。
但是,如果obj.delete()
永远不会真正删除一个持久删除数据库的对象,我就不知道有这种可能性。
我在一个带有以下工件的演示应用中测试了这个:
class Msg {
String text
}
和
class MsgController {
def index() {
[list:Msg.list()]
}
def create() {
def msg = new Msg(text:'hallo '+Msg.count())
msg.save()
redirect action:'index'
}
// this delete does NOT delete the object (hibernate creates no sql "delete from ..." command)
def delete1() {
def msg = Msg.get(params.id)
msg.delete()
flash.message = "msg [$msg.text] with id $msg.id deleted"
redirect action:'index'
}
// this delete does delete the object
def delete2() {
def msg = Msg.get(params.id)
msg.delete(flush:true)
flash.message = "msg [$msg.text] with id $msg.id deleted using flush:true"
redirect action:'index'
}
}
和index.gsp:
<g:if test="${flash.message}">
<p>${flash.message}</p>
</g:if>
<p>
<g:link action="index">index</g:link>,
<g:link action="create">create</g:link>
</p>
<p>
<g:each in="${list}" var="msg">
${msg.id}: [${msg.text}], ***
<g:link action="delete1" id="${msg.id}">delete()</g:link>
<g:link action="delete2" id="${msg.id}">delete(flush:true)</g:link>
<br>
</g:each>
</p>
答案 0 :(得分:1)
出于性能原因,在2.4应用程序中创建的控制器默认为只读事务。这可能是你看到这个的原因,虽然我不是100%肯定。
尽管如此,您应该始终在事务中执行删除操作,因此最好的办法是将删除操作移到服务中并从那里执行(推荐)或使用grails.transaction.Transactional
注释控制器操作,这样可以确保删除是在控制器执行结束时提交的。