我将 Hibernate 与代理一起使用,并且我得到属于类的对象,例如test.DBUser$$EnhancerByCGLIB$$40e99a2d
.
是否有 Hibernate 方法test.DBUser
从代理类中检索基类(在这种情况下) ?我知道Hibernate.getClass()
,但它需要一个Object
, 而我正在寻找一种将 . 作为输入的方法Class
。
虽然我真的很喜欢 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();
}
}
我发现,这比我想象的要容易:只需调用getSuperclass()
代理类来获取未代理的原始类。我不确定这是多么普遍,但它似乎有效。
没有这样的方法。您需要自己编写一个帮助类,以便从代理内部检索包装的对象以及类信息。如果您只需要给定场景中的对象,请尝试删除所有延迟加载。然后 Hibernate 应该给你普通的对象。
考虑尝试不需要该对象。也许您可以重新设计应用程序以使其不再需要它,例如通过在运行时添加包含所需信息的字段。
像这样的类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 一直使用惰性初始化器来获取实现类。