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

问题描述 投票:0回答:4

我将 Hibernate 与代理一起使用,并且获得属于

test.DBUser$$EnhancerByCGLIB$$40e99a2d
等类的对象。

是否有 Hibernate 方法从代理的

class
检索基类(在本例中为 test.DBUser)?我知道
Hibernate.getClass()
,但它需要
Object
,而我正在寻找一种以
Class
作为输入的方法。

java hibernate
4个回答
14
投票

虽然我真的很喜欢 Flavio 发布的方法的简单性,但我无法在生产代码中使用它,除非它被记录为支持的。此外,如果您在

.getImplementation()
上调用
LazyInitializer
,它将强制代理初始化(如果尚未初始化),这会对性能产生负面影响。我想出了这种方法来解决这两个问题:

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

9
投票

我发现,这比我想象的要容易:只需在代理类上调用

getSuperclass()
即可获取未代理的原始类。我不确定这有多普遍,但它似乎有效。


1
投票

test.DBUser$$EnhancerByCGLIB$$40e99a2d
这样的类是动态代理。 “真正的阶级落后”的概念在大多数情况下没有多大意义。每次创建代理时,它都可以是 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 会一直使用惰性初始化程序来获取实现类。


0
投票
没有这样的方法。您需要自己编写一个帮助器类,以便从代理内部检索包装的对象以及类信息。如果您只需要给定场景中的对象,请尝试删除所有延迟加载。然后 Hibernate 应该给你简单的对象。

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

© www.soinside.com 2019 - 2024. All rights reserved.