如何从代理类中检索代理类?

时间:2012-11-24 11:50:16

标签: java hibernate

我正在使用Hibernate和代理,我得到属于test.DBUser$$EnhancerByCGLIB$$40e99a2d等类的对象。

是否有一个Hibernate方法从代理中检索基类(在本例中为test.DBUser)?我知道Hibernate.getClass(),但需要Object,而我正在寻找一种方法,将Class作为输入。

4 个答案:

答案 0 :(得分:7)

虽然我非常喜欢Flavio发布的方法的简单性,但我不能在生产代码中使用它,除非它被记录为支持。此外,如果在LazyInitializer上调用.getImplementation(),它将强制初始化代理(如果尚未启动),这会对性能产生负面影响。我想出了这种解决这两个问题的方法:

public static Class<?> getClassForHibernateObject(Object object) {
  if (object instanceof HibernateProxy) {
    LazyInitializer lazyInitializer =
        ((HibernateProxy) object).getHibernateLazyInitializer();
    return lazyInitializer.getPersistentClass();
  } else {
    return object.getClass();
  }
}

答案 1 :(得分:4)

我发现,它比我想象的要容易:只需在代理类上调用getSuperclass()即可获得未经过代理的原始类。我不确定这是多么普遍,但似乎有效。

答案 2 :(得分:0)

test.DBUser$$EnhancerByCGLIB$$40e99a2d等类dynamic proxies。在大多数情况下,“真实阶级背后”的概念没有多大意义。每次创建代理时,它都可以是Hibernate定义的任何类的实例。

真正要求的是Map的静态{ Class<Proxy>, Class<RealObject>}。我不相信有这样的事情,我也不相信有这个需要。只需查看Hibernate.getClass()的来源:

339     public static Class getClass(Object proxy) {
340     if ( proxy instanceof HibernateProxy ) {
341         return ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer()
342                 .getImplementation()
343                 .getClass();
344     }
345     else {
346         return proxy.getClass();
347     }
348 }

进行静态地图查找以获得真正的类要便宜得多,但是Hibernate会一直到懒惰的初始化程序来获取实现类。

答案 3 :(得分:0)

没有这样的方法。您需要自己编写一个帮助程序类,以便从代理内部检索包装对象,从而检索类信息。如果您只需要给定方案中的对象,请尝试删除所有延迟加载。然后Hibernate应该给你普通的对象。

考虑尝试不需要该对象。也许您可以重新设计应用程序,以便不需要它,例如在运行时添加包含所需信息的字段。