Modifying object in AfterInsert / AfterUpdate - grails

I have a domain object that holds results of a calculation based on parameters that are properties of the same domain object. I'd like to make sure that any time parameters get changed by the user, it recalculates and gets saved properly into the database.
I am trying to do that with afterInsert (to make sure calculation is correct in the first place), and afterUpdate.
However, since my calculation is trying to modify the object itself, it's not working - throwing various hibernate exceptions.
I tried to put the afterUpdate code into a transaction, but that didn't help. I am afraid I am getting into a circular dependency issues here.
The exception I am getting right now is:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [esc.scorecard.PropertyScorecard#27]
Are the GORM events designed for simpler use cases? I am tempted to conclude that modifying the object you are in the middle of saving is not the way to go.

Are you using 1.2.0+?
If you are, you can use .withNewSession in the events closures which is supposed to avoid hibernate chaos.
cheers
Lee

Is there any reason against using beforeInsert and beforeUpdate instead of afterInsert and afterUpdate?
If not, switching to the before* event handlers should fix your issue

Related

Failed to set the ‘_$visited’ property on ‘DOMStringMap’: ‘data-_$visited’ is not a valid attribute name

We are using breeze.js with entity framework to initiate client side entity management.
We randomly get "Failed to set the ‘$visited’ property on ‘DOMStringMap’: ‘data-$visited’ is not a valid attribute name" error the the breeze.js from __toJSONSafe method of it.
does anybody have any idea what could make "obj._$visited" property undefined? It is coming up as undefined and that is causing the issue during call to the saveChanges()
I'm guessing ... it seems like you've added some kind of DOM object to the entity before saving it. I can't imagine how else you could be subjecting the DOMStringMap to __toJSONSafe.
Would need to know more precisely what object (and entity) is involved when you get this exception.
You say it happens randomly. That doesn't make it easy on any of us. If you can make it happen often enough to detect, you could patch the __toJSONSafe method in your local copy of breeze.debug.js so that you can better trap the error and the information about what makes it happen.
Come back and share that information with us.

Get all transient objects

We have a controller where we are trying to carry out search on a domain class. The actual search logic is handled in a service. This search involves use of SomeDomain.withCriteria, fetchMode set to SELECT and createAlias. The search comes back fine with the required results. Once we have the results we redirect to another action in the same controller which handles results. Returning from a controller flushes the session and this is where the controller throws the following exception:
object references an unsaved transient instance - save the transient
instance before flushing
Well it appears as somehow and somewhere in our code a domain object is created and is never saved. The error message is kind enough to show the type of the transient object but it does not inform where and when was it created. This remains a mystery that where this object is created from and I am now looking for ways to get hold of a reference to this object. So my question here is that how can I find all objects which are in a transient state?
I want the reference of this mystery unsaved object just because I want to call discard on it and see how things go on from there. I know that I don't need this object so if it is hanging around somewhere I want to discard it so that it does not end up in throwing exceptions. If someone can also figure out why and where that object gets created then that would be great.
We've had this problem too, and it can be an obnoxious bug to find. Presumably it's possible to find all transients by walking through Hibernate's internal structures, but I've never gone very far into it. Instead, we typically debug via flush() and binary search: flush the session more and more aggressively until it's obvious which operation introduced a transient to your object graph.

How to write changes from one ManagedObject to similar ManagedObjects

I am new with Core Data and have a problem which sounds trivial to solve (at least thinking in SQL) but I can't get my head around that with Core Data.
What I'm trying to do is the following: I have a fetched ManagedObject, do some changes and save it again. This ManagedObject has an attribute id. I want to write the changes I made to this ManagedObject to all the ManagedObjects with the same id.
I was thinking to overwrite willSave: and fetching the other ManagedObjects with the same id there but this won't work because I would encounter an infinite loop there.
Can somebody give me a hint on how to progress from here? Thanks in advance
You could make willSave work, but it isn't going to be a nice bit of code to ignore all of the invalid triggers.
It's better to have a class which manages this functionality, pass in the new data value and the attribute id and allow it to do the fetch and update all of the fetched objects (and trigger the save).
I would, indeed, try to find some better way to deal with it, because actually you should't think of Core Data as of SQL with its triggers.
But actually you can indeed use willSave method and avoid infinite loop. See
NSManagedObject Class Reference willSave method
If you change property values using primitive accessors, you avoid the possibility of infinite recursion, but Core Data will not notice the change you make.
So basically in your willSave method you'll need to call some fetchRequest to get all instances of the same Entity, then loop through them and update using primitive accessor: setPrimitiveValue:forKey:
Also I would advice to verify objects in loop whether they are removed (-isDeleted) and, probably, whether that object is not your current one (by comparing managedObjectIDs)

Benefits of object.get() vs object.read() in Grails

I was skimming some of the Grails documentation and found this bit about the read() method in Grails. If I'm understanding this correctly, you can pull a "read-only" version of an object from the database that will only be saved on an explicit save() call. It seems to me then, that you should use a read() call whenever you have an object that you don't expect to be changed.
But why wouldn't you just always use a read() call? Since the object will be changed to read/write permissions if you save() it anyway, wouldn't it be safer to just read in the object instead of getting it?
You're probably correct - it'd be equivalent in most cases. But Hibernate doesn't require that you call save() since it does dirty checking during a flush and since Grails uses an "Open Session in View" interceptor there will always be a flush at the end of each request. This surprises people who make changes in an instance retrieved by get() that were meant to only be temporary while rendering the view but then the changes get persisted anyway without a save() call. read() would make more sense in that scenario.
One performance optimization is to use http://grails.org/doc/latest/ref/Database%20Mapping/dynamicUpdate.html to only push changed fields to the database. The default is to push all fields whether they're changed or not since then there's no need to generate new SQL for each update. If you read() an instance Hibernate doesn't keep the original data so dynamic update wouldn't be possible since there would be no way to know which fields are dirty.

Attaching object to EF 4 context from MVC view?

I am not sure if that makes any sense, but here is an example.
I have a Category object, that my Service hands to the Controller, which uses AutoMapper to create a CategoryViewModel. Hand that off to the view, serve it to the client.
Now when that gets posted back, AutoMapper creates a Category from the Model sent back, and I hand it to the Service that gives it to the Repository to persist to the database.
My question is, what is the correct way of doing this? I assume the object is a detached object when posted back and I need to attach it to the context, mark it dirty and save changes?
Basically two ways of doing the update of the entity:
Attach the entity to the context, mark it as modified using ObjectStateManager.ChangeObjectState Method, call ObjectContext.SaveChanges Method
Load the original entity from DB, apply changes to the original using ObjectContext.ApplyCurrentValues<TEntity> Method, call ObjectContext.SaveChanges Method
Each of those have their own pros and cons. For example the 1st one does not make round trip to get the original entity but fails to address concurrency as well as tries to update every property of the entity, while the 2nd one works best when employing optimistic concurrency, updates only changed properties, but it does make extra trip to Db to get the original entity.
"I assume the object is a detached object when posted back and I need to attach it to the context, mark it dirty and save changes?"
Yes.
Any one of the links on this page should help:
http://www.google.com/search?rlz=1C1CHFX_enUS410US410&sourceid=chrome&ie=UTF-8&q=working+with+dicsonnected+entities+entity+framework

Resources