Details
-
Type:
Sub-task
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 0.4.2
-
Fix Version/s: None
-
Component/s: Persistence, View technologies
-
Labels:None
Description
We can make domain objects work across the session with a simple trick.
1. Override the add/put methods on HttpSession to detect domain class instances being added to the session
2. Instead of the instance, put in its id in a special serializable object that contains the ID and CLASSNAME of the original domain class.
3. Put the domain instance into the REQUEST context, using a special name like _grails_domain_ATTRIBNAME
The object ID is now safely in the session, and the request has a ref to the instance.
When retrieving the object from the session:
1. Get the attribute from session. If it is our special wrapper object, ask the request if it has _grails_domain_ATTRIBNAME.
2. If it does, just return this (this allows access to the var during the request in which it was added to the session)
3. If it does not, extract CLASSNAME from our wrapper, do CLASSNAME.get(ID) and put this value into the REQUEST context again as _grails_domain_ATTRIBNAME
4. Return the loaded instance.
This should give us transparent and scalable session access to domain object.s
Having thought about this more there are two issues:
1. Putting stuff in session for later use, always in sync with DB
2. Putting stuff in session for use with custom control over when flushed and reloaded
The above solution works for part 1. Part 2 requires some kind of flush() method on the domain object, or a wrapper that defers all property lookups to the encapsulated domain object instance, but has a flush() method, such that the next access to a property will cause get(id) to be called again and reload the object.
Perhaps however this can be integrated somehow into forthcoming cache control on domain classes so that we have a flush() method on domain classes, and have Session be smart and do whatever is needed to "detach" the object in the session until it is flushed again explicitly or by the cache timeout property set on it?