Quantcast

When does object data get persisted back to database?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

When does object data get persisted back to database?

webmediauk
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

Ian Roberts
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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

webmediauk
Thank you Ian,
If I call .discard() on a list will it detach all objects within the list from the session?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

Ian Roberts
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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

Graeme Rocher-2
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:

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


--
Sent from the Grails - user mailing list archive at Nabble.com.

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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

Scott6666
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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: When does object data get persisted back to database?

Ian Roberts
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


Loading...