|
Hey Guys,
I was under the impression that data would not be persisted back to the database until I called .save() or .save( flush: true ) on an object? I have an object which has a property "impressions", which is basically a count of how many times that object has been viewed. This value is calculated every half hour by a job and saved back to the database. I then have an action which shows "impressions" for a particular date range. So in my code I calculate the "impressions" for the date range and then temporarily reset my objects "impressions" property like this: object.impressions = dateRangeCalulatedImpressions [ objectInstance : object ] This all works fine but for some reason the value for object.impressions is getting persisted back to the database even though I am not calling .save() anywhere? Can someone please clarify how GORM decides when to persist the data back to the database? Thanks Barry |
|
On 24/02/2012 11:57, webmediauk wrote:
> Can someone please clarify how GORM decides when to persist the data back to > the database? Newly created domain objects (new MyDomainObject(...)) are transient until you call .save(), at which point they become attached to the Hibernate session, but objects that were fetched from the database are attached to the Hibernate session from the start. Any changes to an attached object will be persisted to the DB at the end of the session (typically the end of the current request if this is happening in a controller). If you want to avoid this you can detach the object from the session by calling object.discard(). Another manifestation of this is: def myObj = new MyDomainObject(foo:'bar') myObj.save() // myObj is now attached to session myObj.foo = 'baz' // so this change will persist when the session closes Ian -- Ian Roberts | Department of Computer Science [hidden email] | University of Sheffield, UK --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Thank you Ian,
If I call .discard() on a list will it detach all objects within the list from the session? |
|
On 24/02/2012 12:19, webmediauk wrote:
> Thank you Ian, > If I call .discard() on a list will it detach all objects within the list > from the session? Normal groovy syntax should allow myListOfDomainObjects*.discard() Ian -- Ian Roberts | Department of Computer Science [hidden email] | University of Sheffield, UK --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by webmediauk
default flush mode in Grails is auto, so changes are detected and flushed automatically when a query is executed and/or at the end of the request.
You could use discard() as described, but maybe a better way is to set the flush mode to MANUAL for the scope of the request. This can be done by using a service and marking the method as read-only: @Transactional(readOnly=true) def listBooks() { Book.list() } Or if you only have a controller/domain you can use the withTransaction method: Book.withTransaction(new DefaultTransactionDefinition(readOnly:true)) { Book.list() } We should probably make this simpler btw and have a way do easily do read-only operations from controllers… nevertheless hope this helps Cheers -- Graeme Rocher On Friday, February 24, 2012 at 12:57 PM, webmediauk wrote:
|
|
In reply to this post by Ian Roberts
Very nice succinct explanation. The attachment part is usually confusing to newcomers.
Also should note that saving with flush:true persists to the database immediately rather than waiting until the end of the session, if that behavior is desired. Ian, do you have any comments on "getting" an object that has not yet been flushed to the database. Are there any tricks there since the db and the Hibernate session are not the same? Also, how does an invalid object work with the session? I see posts on the lists that they are silently discarded to the surprise of at least one user. On Feb 24, 2012, at 7:05 AM, Ian Roberts <[hidden email]> wrote: > On 24/02/2012 11:57, webmediauk wrote: >> Can someone please clarify how GORM decides when to persist the data back to >> the database? > > Newly created domain objects (new MyDomainObject(...)) are transient > until you call .save(), at which point they become attached to the > Hibernate session, but objects that were fetched from the database are > attached to the Hibernate session from the start. Any changes to an > attached object will be persisted to the DB at the end of the session > (typically the end of the current request if this is happening in a > controller). If you want to avoid this you can detach the object from > the session by calling object.discard(). > > Another manifestation of this is: > > def myObj = new MyDomainObject(foo:'bar') > myObj.save() // myObj is now attached to session > myObj.foo = 'baz' // so this change will persist when the session closes > > Ian > > -- > Ian Roberts | Department of Computer Science > [hidden email] | University of Sheffield, UK > > --------------------------------------------------------------------- > 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 |
|
On 24/02/2012 14:28, Scott Eisenberg wrote:
> Very nice succinct explanation. The attachment part is usually > confusing to newcomers. > > Also should note that saving with flush:true persists to the database > immediately rather than waiting until the end of the session, if > that behavior is desired. That is true, but if you then modify the object again after the flush those changes will persist at the end of the session in the normal way. > Ian, do you have any comments on "getting" an object that has not yet > been flushed to the database. Are there any tricks there since the db > and the Hibernate session are not the same? If you .get() the same ID more than once *within the same Hibernate session* then you'll get two references to the same in-memory object, including any changes that have not yet been flushed, but I don't think there's any way to see unflushed changes from a *different* session. > Also, how does an invalid object work with the session? I see posts > on the lists that they are silently discarded to the surprise of at > least one user. As I understand it, if the object is not valid then it won't get flushed to the database but you'll still have the same behaviour regarding multiple .get()s in the same session giving you the same (now invalid) object. Ian -- Ian Roberts | Department of Computer Science [hidden email] | University of Sheffield, UK --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
| Powered by Nabble | Edit this page |
