I have an object (O) with an association to a list of another object (List<E>) and they have bidirectional association in hibernate setup so there is a reference of O from E as well.
I have screens that edit O and E separately.
When I load a screen that edit O, I would initalise all of the association to E and present it on the screen so that user can edit that list (adding/removing).
In addition to that I also allow user to edit individual object E from the list presented in O screen.
The problem I find is that whenever I try to edit E, and then save O, I get hibernate session closed exception.
org.hibernate.HibernateException: disconnected session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:452)
at org.hibernate.Hibernate.initialize(Hibernate.java:309)
at net.sf.hibernate4gwt.core.hibernate.HibernateUtil.initializeProxy(HibernateUtil.java:361)
at net.sf.hibernate4gwt.core.beanlib.merge.MergeCollectionReplicator.createToCollection(MergeCollectionReplicator.java:114)
at net.sf.beanlib.provider.replicator.CollectionReplicator.replicateCollection(CollectionReplicator.java:72)
at net.sf.beanlib.hibernate3.Hibernate3CollectionReplicator.replicateCollection(Hibernate3CollectionReplicator.java:79)
at net.sf.beanlib.provider.replicator.ReplicatorTemplate.replicate(ReplicatorTemplate.java:91)
at net.sf.beanlib.provider.BeanTransformer.transform(BeanTransformer.java:123)
at net.sf.beanlib.provider.BeanPopulator.doit(BeanPopulator.java:169)
at net.sf.beanlib.provider.BeanPopulator.processSetterMethod(BeanPopulator.java:133)
at net.sf.beanlib.provider.BeanPopulator.populate(BeanPopulator.java:104)
at net.sf.hibernate4gwt.core.LazyKiller.populate(LazyKiller.java:253)
at net.sf.hibernate4gwt.core.LazyKiller.attach(LazyKiller.java:211)
at net.sf.hibernate4gwt.core.HibernateBeanManager.mergePojo(HibernateBeanManager.java:562)
at net.sf.hibernate4gwt.core.HibernateBeanManager.merge(HibernateBeanManager.java:317)
I've look through hibernate4gwt code and the problem is that editing E involves loading E by Id, as a result O is being reloaded (without lazy associations to E being initalised). This newly loaded O is then placed in the session which override the original O what was loaded with association E properly initalised.
Subsequently, when I then try to save O, hibernate4gwt finds that association E is not initialised so it then go ahead and tries to intialise the persistent bag which result in session closed exception.
A couple of details to note
* I'm using stateful session (httpstore)
* I'm using spring transaction annotation (as opposed to session filter - transaction per request pattern)
What's your thought on this?
I haven't looked at the stateless model but I don't want to add too much class dependencies to the object model.
Another possiblity is if when loading E and if it is about to load the back reference to O, if I can intercept it and use what has been previously loaded in the context that would avoid this situation as ideally in a drilldown/chain of editing screens, I don't really want my session store to get overridden with subsequent edit screens because eventually after editing all of the drill down I would want to save the parent screens.
Look forward to hear from you.
Cheers,
rOnn c.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
FYI for other readers, I've moved on to the stateless model and it fixes this problem. Needless to say that I'm very relieved!
Looks like a fundamental flaw in the stateful model where it's state cache can be overwritten by subsequent load.
e.g. if you look at the following sequence of operation.
Load object A
Load object B which also happens to load associated A incompletely. At this point in time object A in the state cache will now be overwritten.
Save object B - no problem.
Save object A which was originally loaded in the first screen <- failed because A in the cache is not the same as A that was originally loaded on the screen.
I'm happier using stateless model but have not figure out Dynamic Proxy yet as some one has mentioned that it might not work with BeanModel proxy for GXT?? Anyone know if this is true?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You are right : proxy informations are stored in the HTTP session with the persistent ID as a key, which can lead to data loss :-(
I will have to think about another way to create unique ID...
About the GXT BeanModel, as far as i can remember, GXT does not support Dynamic proxy subclassing. In my mind, that's probably a GXT issue...
Regards
Bruno
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Bruno,
I've come across an interesting problem.
I have an object (O) with an association to a list of another object (List<E>) and they have bidirectional association in hibernate setup so there is a reference of O from E as well.
I have screens that edit O and E separately.
When I load a screen that edit O, I would initalise all of the association to E and present it on the screen so that user can edit that list (adding/removing).
In addition to that I also allow user to edit individual object E from the list presented in O screen.
The problem I find is that whenever I try to edit E, and then save O, I get hibernate session closed exception.
org.hibernate.HibernateException: disconnected session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:452)
at org.hibernate.Hibernate.initialize(Hibernate.java:309)
at net.sf.hibernate4gwt.core.hibernate.HibernateUtil.initializeProxy(HibernateUtil.java:361)
at net.sf.hibernate4gwt.core.beanlib.merge.MergeCollectionReplicator.createToCollection(MergeCollectionReplicator.java:114)
at net.sf.beanlib.provider.replicator.CollectionReplicator.replicateCollection(CollectionReplicator.java:72)
at net.sf.beanlib.hibernate3.Hibernate3CollectionReplicator.replicateCollection(Hibernate3CollectionReplicator.java:79)
at net.sf.beanlib.provider.replicator.ReplicatorTemplate.replicate(ReplicatorTemplate.java:91)
at net.sf.beanlib.provider.BeanTransformer.transform(BeanTransformer.java:123)
at net.sf.beanlib.provider.BeanPopulator.doit(BeanPopulator.java:169)
at net.sf.beanlib.provider.BeanPopulator.processSetterMethod(BeanPopulator.java:133)
at net.sf.beanlib.provider.BeanPopulator.populate(BeanPopulator.java:104)
at net.sf.hibernate4gwt.core.LazyKiller.populate(LazyKiller.java:253)
at net.sf.hibernate4gwt.core.LazyKiller.attach(LazyKiller.java:211)
at net.sf.hibernate4gwt.core.HibernateBeanManager.mergePojo(HibernateBeanManager.java:562)
at net.sf.hibernate4gwt.core.HibernateBeanManager.merge(HibernateBeanManager.java:317)
I've look through hibernate4gwt code and the problem is that editing E involves loading E by Id, as a result O is being reloaded (without lazy associations to E being initalised). This newly loaded O is then placed in the session which override the original O what was loaded with association E properly initalised.
Subsequently, when I then try to save O, hibernate4gwt finds that association E is not initialised so it then go ahead and tries to intialise the persistent bag which result in session closed exception.
A couple of details to note
* I'm using stateful session (httpstore)
* I'm using spring transaction annotation (as opposed to session filter - transaction per request pattern)
What's your thought on this?
I haven't looked at the stateless model but I don't want to add too much class dependencies to the object model.
Another possiblity is if when loading E and if it is about to load the back reference to O, if I can intercept it and use what has been previously loaded in the context that would avoid this situation as ideally in a drilldown/chain of editing screens, I don't really want my session store to get overridden with subsequent edit screens because eventually after editing all of the drill down I would want to save the parent screens.
Look forward to hear from you.
Cheers,
rOnn c.
FYI for other readers, I've moved on to the stateless model and it fixes this problem. Needless to say that I'm very relieved!
Looks like a fundamental flaw in the stateful model where it's state cache can be overwritten by subsequent load.
e.g. if you look at the following sequence of operation.
Load object A
Load object B which also happens to load associated A incompletely. At this point in time object A in the state cache will now be overwritten.
Save object B - no problem.
Save object A which was originally loaded in the first screen <- failed because A in the cache is not the same as A that was originally loaded on the screen.
I'm happier using stateless model but have not figure out Dynamic Proxy yet as some one has mentioned that it might not work with BeanModel proxy for GXT?? Anyone know if this is true?
Hi Ronn,
You are right : proxy informations are stored in the HTTP session with the persistent ID as a key, which can lead to data loss :-(
I will have to think about another way to create unique ID...
About the GXT BeanModel, as far as i can remember, GXT does not support Dynamic proxy subclassing. In my mind, that's probably a GXT issue...
Regards
Bruno