Calling a delete() on a domain object, try to delete the object two times

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Calling a delete() on a domain object, try to delete the object two times

mjfan80
Hi to all
I try to google the question, and try to search here but i didn't find answer, so i try to post a new topic

I have a problem with my project
I have a relative big grails project, i'm use gorm intensely, making many CRUD operation withou problem (except sum bug that is known)

Now i have a problem with a domain class... when i call the delete() command over an instance of this class, grails try to call two times the delete

This is the domain class

package com.fdlservizi.sse

import com.fdlservizi.sse.acl.Utente
import com.fdlservizi.sse.shared.client.dominio.Chiamata as ChiamataJava

/**
 * Domain class chiamata,
 */
class Chiamata {
    def utilityService
    [...]
    public Mail mail
    static mapping = {
        version false
        columns {
            [...]
        }
        id generator: "assigned"
    }
    static constraints = {
        [...]
    }
    static transients = ["locale", "edificio", "dtSched", "modificataDa", "ruleActivationId", "messaggioMail", "mail"]

    String id               
    [...]

    static hasMany = [attScheds: AttSched, bollas: Bolla]

    def beforeInsert = {
        println "partito il beforeinsert"
        this.lastMod = this.utilityService.getSqlDate()
        println "lastmod = " + lastMod
        def respchiam = this.imp?.contrZona?.dipendente
        if (respchiam != null) this.respChiam = respchiam
        this.contratto = this.utilityService.getContrattoByImpianto(this.imp)
        this.cli = this.contratto?.cliente
    }

    def beforeUpdate = {
        lastMod = this.utilityService.getSqlDate()
        def respchiam = this.imp?.contrZona?.dipendente
        if (respChiam != null) respChiam = respchiam
    }

    def beforeDelete = {
        def atts = AttSched.findAllByChiamata(this)
        println "sono in chiamata.beforedelete, attscheds = " + atts
        atts.each {
            it.chiamata = null
            if (!it.save(flush: true)) {
                it.errors.each {log.error(it)}
            }
        }
        def messaggioLog = "L'utente ${loginService.getDescrUtente()} (${loginService.getIdUtente()}) ha cancellato la chiamata in data: " + new Date().format('dd/MM/yyyy HH:mm')
        generaMail(messaggioLog)
    }

    def afterDelete = {
        println "sono in chiamata.afterdelete"
        def messaggioLog = "L'utente ${loginService.getDescrUtente()} (${loginService.getIdUtente()}) ha cancellato la chiamata in data: " + new Date().format('dd/MM/yyyy HH:mm')
        LogChiamata logChiamata = new LogChiamata(["idChiamata": this.id, "messaggio": messaggioLog, "note": this.noteLog, "cancellata": LogChiamata._isCancellataTrue])
        logChiamata.withNewSession {
            if (!logChiamata.save(insert: true)) {
                log.error "non sono riuscito a salvare il log"
                logChiamata.errors.each { log.error it}
            }
        }
    }

    public boolean fdlSave() {
        fdlSave(insert: false, flush: false, log: true, mail: false)
    }

    public boolean fdlSave(Map params) {
        [..]
            oldChiamata = null
            println "prima di inserire la chiamata"
            this.validate()
            this.errors.each {log.error it}
            risultato = this.save(insert: true, flush: params.flush)
    }

    [...]
}
 
so there is some gorm event used, like beforedelete and after delete, and i "override" the save() command, calling, when i want to save an instance, the fdlsave() command (that call the save())

The problem is in this service where i call the delete
class EliminaChiamataService {
    static expose = ['gwt:com.fdlservizi.sse.web.client.servizi']
    def utilityService

    void eliminaChiamata(String idChiamata) {
        println "eliminaChiamata(${idChiamata})"
        def chiam = Chiamata.get(idChiamata)
        try {
            chiam.delete()
            println("e' stata cancellata la chiamata: " + idChiamata);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed.
            System.err.println("problemi: " + ex + " sulla cancellazione della chiamata: " + idChiamata);
        }
    }
}
when i call the eliminaChiamata function, grails just print one time the "elimina chiamata" line... so the problem is not in the way i call the command, but then i see in the stacktrace two time the println line
 println "sono in chiamata.beforedelete, attscheds = " + atts
that i have in the beforedelete event in the domain class

Why grails try to delete two times the instance?
I just call one time the "domainclassinstance.delete()" code (because i see only one time the println line over it
but then grails try to delete the domaininstance two time... i see two times the println line in the befeoredelete event and if i log hibernate i see two time the DELETE sql cose
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

rawi
Once upon the time I experienced this 2-times-delete attempt...

I could follow the issue till understanding, that hibernate tries a second time to delete after entering the catch block.
To that time I thought also the issue would be related to the mapping or not mapping of the version property but it was the other way round in my case...

I'd say, your hibernate gets in the background an error from the database, which cannot delete the Chiamata record. Then you are entering the catch block, where a second attempt to delete will be made (_why_ ???)... something like here:

http://jira.grails.org/browse/GRAILS-5232
(my copy/paste in the jira didn't take at that time all the new lines, it is a bit difficult to read)

I saw that Chiamata has a second 1:n relation on Bolla.

In beforeDelete you set all foreign keys of Chiamata in AttSched to null but don't do the same with Bolla.
Could be, that this is the cause to not be able to delete Chiamata, because an ON DELETE RESTRICT in Bolla?

Even if this first solves the problem, the issue with the second delete attempt in the catch block remains.
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
Yes, there was problem with bolla
now i have this

 def beforeDelete = {
        println "sono in chiamata.beforedelete"
            def atts = AttSched.findAllByChiamata(this)    //non si può usare attscheds perchè bomba, non so perchè
            atts?.each {
                it.chiamata = null
                if (!it.save(flush: true)) {
                    it.errors.each {log.error(it)}
                }
            }
            def bolle = Bolla.findAllByChiamata(this) //non si può usare bollas perchè bomba, non so perchè
            bolle?.each {
                it.chiamata = null
                if (!it.save(flush: true)) {
                    it.errors.each {log.error(it)}
                }
            }
    }

but the problem with the second delete attemp is still here
hibernate try to delete the chiamata the first time, and it's working well (everything is deleted)
but then hibernate try to delete chiamata the second time (WHY???????????????????) and so i get errors
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

rawi
Well, just a shot into the dark.... based on the already discussed feature of the save closure in a controller, to save the object despite not calling .save()...

May be the delete closure does the same and tries a delete on it's own additionally to your service if you instantiate the Chiamata there too?

I'd say, for the 3 lines you wouldn't need a service... Try and take the lines:
        def chiam = Chiamata.get(idChiamata)
        try {
            chiam.delete()
            println("e' stata cancellata la chiamata: " + idChiamata);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed.
            System.err.println("problemi: " + ex + " sulla cancellazione della chiamata: " + idChiamata);
        }
and put them directly into the delete closure of the controller.
...And you are sure you don't entry the catch block any more... Check may be if (chiam) exists

What happens?
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
I have to use a service, and not a controller, because i'm calling this service as a RPC from a GWT client...
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
No one have the solution about this problem?
I tried many think, but i really can handle this strange behavior
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
I still have this problem.
No one have suggestions?
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

Graeme Rocher-2
Create an example that reproduces the issue and attach to a JIRA issue


On Wed, Jul 24, 2013 at 10:23 AM, mjfan80 <[hidden email]> wrote:
I still have this problem.
No one have suggestions?



--
View this message in context: http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try-to-delete-the-object-two-times-tp4413846p4647133.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email





--
Graeme Rocher
Grails Project Lead
SpringSource
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

snimavat
In reply to this post by mjfan80
Can you try this

     Chiamata.withTransaction { tx ->
      def chiam = Chiamata.get(idChiamata)
        try {
            chiam.delete()
            println("e' stata cancellata la chiamata: " + idChiamata);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed.
            System.err.println("problemi: " + ex + " sulla cancellazione
della chiamata: " + idChiamata);
           tx.setRollbackOnly()
        }
}

Try it and see what happens ?
Notice Chiamata.withTransaction and  tx.setRollbackOnly(),

Also, Do AttSched & Bolla belongsTo Chiamata than delete should cascade.
You need to figure out why the delete is failing at the first place.

Sudhir N
[Independent Grails/Java developer]

-----Original Message-----
From: mjfan80 [mailto:[hidden email]]
Sent: Wednesday, July 24, 2013 1:53 PM
To: [hidden email]
Subject: [grails-user] Re: Calling a delete() on a domain object, try to
delete the object two times

I still have this problem.
No one have suggestions?



--
View this message in context:
http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try-
to-delete-the-object-two-times-tp4413846p4647133.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
I will try
but the problem is that the first call of delete is working good... the chiamata is really deleted from DB.
The real problem is that gorm is calling delete the second time... why?


2013/7/24 Sudhir N <[hidden email]>
Can you try this

     Chiamata.withTransaction { tx ->
      def chiam = Chiamata.get(idChiamata)
        try {
            chiam.delete()
            println("e' stata cancellata la chiamata: " + idChiamata);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed.
            System.err.println("problemi: " + ex + " sulla cancellazione
della chiamata: " + idChiamata);
           tx.setRollbackOnly()
        }
}

Try it and see what happens ?
Notice Chiamata.withTransaction and  tx.setRollbackOnly(),

Also, Do AttSched & Bolla belongsTo Chiamata than delete should cascade.
You need to figure out why the delete is failing at the first place.

Sudhir N
[Independent Grails/Java developer]

-----Original Message-----
From: mjfan80 [mailto:[hidden email]]
Sent: Wednesday, July 24, 2013 1:53 PM
To: [hidden email]
Subject: [grails-user] Re: Calling a delete() on a domain object, try to
delete the object two times

I still have this problem.
No one have suggestions?



--
View this message in context:
<a href="http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try- to-delete-the-object-two-times-tp4413846p4647133.html" target="_blank">http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try-
to-delete-the-object-two-times-tp4413846p4647133.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
In reply to this post by snimavat
I will try
but the problem is that the first call of delete is working good... the
chiamata is really deleted from DB.
The real problem is that gorm is calling delete the second time... why?



--
View this message in context: http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try-to-delete-the-object-two-times-tp4413846p4647137.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

mjfan80
In reply to this post by snimavat
thanks snimavat
the withTransaction worked perfect, now the delete is called only one time
(but now i don't have the afterdelete event)
Reply | Threaded
Open this post in threaded view
|

Re: Calling a delete() on a domain object, try to delete the object two times

snimavat
In reply to this post by snimavat

That's because Your delete is failing, try to print stack trace.


Sudhir N
[Independent Grails/Java developer]


-----Original Message-----
From: mjfan80 [mailto:[hidden email]]
Sent: Wednesday, July 24, 2013 3:21 PM
To: [hidden email]
Subject: [grails-user] Re: Calling a delete() on a domain object, try to
delete the object two times

thanks snimavat
the withTransaction worked perfect, now the delete is called only one time
(but now i don't have the afterdelete event)



--
View this message in context:
http://grails.1312388.n4.nabble.com/Calling-a-delete-on-a-domain-object-try-
to-delete-the-object-two-times-tp4413846p4647140.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email