如何解析hibernate对象,以便支持多态?
考虑以下示例。类A和B是两个休眠实体。 B有两种亚型C和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
}
}
}
此代码无法执行C或D块,因为B集合已延迟加载,并且B的所有实例都是Hibernate代理。我想要一种解开每个实例的方法。
注意:我意识到可以优化查询以急切地获取所有B。我正在寻找替代方案。
答案 0 :(得分:18)
这是我们的解决方案,添加到我们的持久性工具:
public T unproxy(T proxied)
{
T entity = proxied;
if (entity instanceof HibernateProxy) {
Hibernate.initialize(entity);
entity = (T) ((HibernateProxy) entity)
.getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
答案 1 :(得分:2)
使用HibernateProxy和getImplementationMethod的解决方案是正确的。
但是,我假设你遇到了这个问题,因为你的集合被定义为一个接口,而hibernate正在为接口提供代理。
这导致了设计问题,为什么“if”与“instanceof”而不是使用接口方法来做你需要的。
所以你的循环变成了:
for(B nextB : nextA.getBAssociations() {
nextB.doSomething();
}
这样,hibernate会将对“doSomething()”的调用委托给实际的实现对象,而你永远不会知道它们的区别。
答案 2 :(得分:0)
如今,Hibernate具有专用的方法:org.hibernate.Hibernate#unproxy(java.lang.Object)