Hi. I'm using Hibernate 2.1.3
I'm having trouble initializing some lazy-loaded objects when ehcache is enabled. If I disable the cache, I do not have any problems. This is a distributed J2EE/EJB application, and I'm creating a new session for each session bean call if db access is necessary.
I have a parent/child relationship where the parent has a Set of children.
I have Hibernate set to use field access, and the getters in the Parent class contain code to initialize the field in question if it isn't initialized. So, to avoid unintentional recursion, the method "getChildren" included below uses DirectPropertyAccessor to get at Parent.children
I want to load the children of the parent, so I do as follows:
Code:
public java.util.Set getChildren(Parent parent) {
// PersistentSession is just a wrapper for net.sf.hibernate.Session
// PersistentSession.getPersistentSession() returns net.sf.hibernate.Session
PersistentSession sess = new PersistentSession();
try {
// there's a reason I'm not using the 'parent' object passed-in, but
// it's not relevant to the issue at hand
Parent tmp;
tmp =
(Parent) sess
.getPersistentSession()
.load(Parent.class, new Long(parent.getId()));
Hibernate.initialize(tmp);
if (tmp instanceof HibernateProxy) {
tmp = (Parent) HibernateProxyHelper.getLazyInitializer((HibernateProxy) tmp).getImplementation();
}
Object children = new DirectPropertyAccessor().getGetter(tmp.getClass(), "children").get(tmp);
Hibernate.initialize(children);
if (children != null) {
for (Iterator it = ((Set) children).iterator(); it.hasNext(); ) {
Object o = it.next();
Hibernate.initialize(o);
}
}
return (java.util.Set) children;
} catch (HibernateException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} finally {
sess.close();
}
}
The first thing of note above is that I have to check if "tmp" implements "HibernateProxy". I put this in because I found that even after calling Hibernate.initialize(tmp), the 'tmp' was still not correctly initialized. This only happens with ehcache enabled. Why is this happening? Is it safe for me to call 'getImplementation' as I do above?
Next, I find that sometimes the Set 'children' contains HibernateProxy objects instead of initialized objects and even after iterating over the children and calling Hibernate.initialize on each one, they are still proxies. I was considering using the same approach as above, where I would replace the objects in the Set with the values returned by getImplementation(), but I thought this might be problematic if the Set had cascade="all-delete-orphan". Again, if ehcache is disabled, then Hibernate.initialize(children) works as expected.
Also, this usually works the first time through, but not subsequent times.
So:
1 - What am I doing wrong that results in my objects still being HibernateProxy's even after I Hibernate.initialize them?
2 - Should I be staying away from lines like HibernateProxyHelper.getLazyInitializer((HibernateProxy) tmp).getImplementation()???
Thanks for any help...