2

I want to get a domain entity in grails in detached state when there is another domain entity for same id in same method.

I followed this How do you disconnect an object from it's hibernate session in grails? as a way to get a detached domain entity in grails.

def id = 23L;
def userInstance = User.get(id)
def oldInstance = User.get(id).discard()

userInstance.properties = params

userInstace.save(flush:true)

// Now, I want to compare properties of oldInstance and userInstance
// But I get null for oldInstance

So, how can I get a domain entity in grails in details such that it is detached from gorm session?

Community
  • 1
  • 1
TheKojuEffect
  • 20,103
  • 19
  • 89
  • 125

1 Answers1

4

discard does not return the instance itself. It returns nothing (void) but evicts the object getting persisted in future. Use it as:

def oldInstance = User.get(id)
oldInstance.discard()

On a side note, if the sole reason is to compare the old and new values of the properties in the instance then you can use dirtyPropertyNames and getPersistentValue() before flushing the instance as below:

userInstance.properties = params

userInstance.dirtyPropertyNames?.each { name ->
    def originalValue = userInstance.getPersistentValue( name )
    def newValue = userInstance.name
}

//Or groovier way
userInstance.dirtyPropertyNames?.collect { 
    [
        (it) : [oldValue: userInstance.getPersistentValue( it ), 
                newValue: userInstance.it] 
    ] 
}
dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • Will `userInstance.dirtyPropertyNames` work after calling `userInstance.save()` – TheKojuEffect May 12 '14 at 04:28
  • No this has to used before save. Once saved, all dirty properties will be flushed with new values. Old values will be lost. – dmahapatro May 12 '14 at 04:30
  • Thanks. I'm using Intellij and I get `cannot resolve symbol` in `dirtyPropertyNames` and `userInstance.getPersistentValue`. Any idea? – TheKojuEffect May 12 '14 at 06:23
  • When I load a domain from the database, then change some properties and then call `getPersistentValue` on a field, what exactly does it return? I guess it's the value originally loaded from the database, it does not actually make another database query to get the current value of the field, right? My point is, it's possible that between the initial loading of the domain from the database and the point when I want to save it back, some other thread has overwritten the record in the database and I need to get the current values from the database without losing the changes made to the domain. – David Ferenczy Rogožan Oct 23 '19 at 21:58
  • So I have tried to load another instance of the domain from the database inside the domain, like `def current = get(id)`, but it actually returns the same instance of the domain, so `current == this`. When I call `current.refresh()` it actually reloads data from the database but it also updates `this` so I lose all changes made to it. I need to keep `this` untouched and at the same time load the current data from the database so I can compare the differences between `this` and `current`. Is it possible, please? – David Ferenczy Rogožan Oct 23 '19 at 22:06