我将 Hibernate 与代理一起使用,并且获得属于
test.DBUser$$EnhancerByCGLIB$$40e99a2d
等类的对象。
是否有 Hibernate 方法从代理的
class检索基类(在本例中为
test.DBUser
)?我知道 Hibernate.getClass()
,但它需要 Object
,而我正在寻找一种以 Class
作为输入的方法。
虽然我真的很喜欢 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();
}
}
我发现,这比我想象的要容易:只需在代理类上调用
getSuperclass()
即可获取未代理的原始类。我不确定这有多普遍,但它似乎有效。
像
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 会一直使用惰性初始化程序来获取实现类。
考虑尝试不再需要该对象。也许您可以重新设计应用程序,以便不需要它,例如通过在运行时添加包含所需信息的字段。