简体   繁体   中英

delete() not does persist anymore in grails 2.4.1

While migrating a project from 1.3.7 to 2.4.1 I stumbled over several things. One of them is, that I found obj.delete() does not persist anymore in 2.4.1 unless I use obj.delete(flush:true) .

When I read the Grails UserGuide where it says '... the instance being deleted immediately' I understand that the flush:true argument is an option to force persisting the object immediately instead of 'letting it persist when hibernate thinks its ok'.

But if obj.delete() never really deletes an object in terms of persiting the delete to the database, I don't get clue of having this possibility.

I testet this in a demo app with the following artifacts:

class Msg {
    String  text
}

and:

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'
    }
}

and 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>

Controllers created in 2.4 apps default to read-only transactions for performance reasons. This could be the reason you're seeing this, although I'm not 100% certain.

Nevertheless you should always perform a delete within a transaction so the best thing to do is either move the delete to a service and do it from there (recommended) or annotation your controller action with grails.transaction.Transactional , this will ensure the delete is committed at the end of controller execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM