java 如何取消代理休眠对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11228838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:18:22  来源:igfitidea点击:

how to unproxy a hibernate object

javahibernate

提问by Peter Bratton

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.

考虑以下示例。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
        }
    }
}

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.

此代码无法执行 C 或 D 块,因为 B 集合已被延迟加载,并且 B 的所有实例都是 Hibernate 代理。我想要一种取消代理每个实例的方法。

Note: I realize the query can be optimized to eagerly fetch all B's. I'm looking for an alternative.

注意:我意识到可以优化查询以急切地获取所有 B。我正在寻找替代方案。

回答by Peter Bratton

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;
}

回答by Radek Posto?owicz

Nowadays Hibernate has dedicated method for that: org.hibernate.Hibernate#unproxy(java.lang.Object)

现在 Hibernate 有专门的方法:org.hibernate.Hibernate#unproxy(java.lang.Object)

回答by Matt

The solution using the HibernateProxy and the getImplementationMethod is correct.

使用 HibernateProxy 和 getImplementationMethod 的解决方案是正确的。

However, I assume you're running into this because your collection is defined as an interface, and hibernate is presenting proxies to the interface.

但是,我假设您遇到了这个问题,因为您的集合被定义为一个接口,而 hibernate 正在向该接口提供代理。

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.

这导致了设计问题,为什么要使用“if”和“instanceof”而不是使用接口方法来完成您需要的操作。

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.

这样,hibernate 会将对“doSomething()”的调用委托给实际的实现对象,而您永远不会知道其中的区别。