how to unproxy a hibernate object [duplicate]
How can I unproxy a hibernate object, such that polymorphism would be supported?
Consider the following example. Classes A and B are two hibernate entities. B has two subtypes C and D.
List<A> resultSet = executeSomeHibernateQuery();
for(A nextA : resultSet) {
for(B nextB : nextA.getBAssociations() {
if(nextB instanceof C) {
// do something for C
} else if (nextB instanceof D) {
// do something for D
}
}
}
This code fails to execute either the C or D block, since the B collection has been lazy loaded, and all instances of B are Hibernate proxies. I'd like a way to unproxy each instance.
Note: I realize the query can be optimized to eagerly fetch all B's. I'm looking for an alternative.
Solution 1:
Here's our solution, added to our persistence utils:
public T unproxy(T proxied)
{
T entity = proxied;
if (entity instanceof HibernateProxy) {
Hibernate.initialize(entity);
entity = (T) ((HibernateProxy) entity)
.getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
Solution 2:
Nowadays Hibernate has dedicated method for that: org.hibernate.Hibernate#unproxy(java.lang.Object)
Solution 3:
The solution using the HibernateProxy and the getImplementationMethod is correct.
However, I assume you're running into this because your collection is defined as an interface, and hibernate is presenting proxies to the interface.
This leads to the design question, of why have the "if" with the "instanceof" instead of using a interface method to do what you need.
So your loop becomes:
for(B nextB : nextA.getBAssociations() {
nextB.doSomething();
}
That way, hibernate would delegate the call to "doSomething()" to the actual implementation object, and you'd never know the difference.