我使用Hibernate與代理,並且我得到屬於類的對象,如test.DBUser$$EnhancerByCGLIB$$40e99a2d
。如何從代理類中檢索代理類?
是否有Hibernate方法從代理的類中檢索基類(在這種情況下爲test.DBUser
)?我知道Hibernate.getClass()
,但它需要Object
,而我正在尋找一種方法,它需要輸入Class
。
我使用Hibernate與代理,並且我得到屬於類的對象,如test.DBUser$$EnhancerByCGLIB$$40e99a2d
。如何從代理類中檢索代理類?
是否有Hibernate方法從代理的類中檢索基類(在這種情況下爲test.DBUser
)?我知道Hibernate.getClass()
,但它需要Object
,而我正在尋找一種方法,它需要輸入Class
。
我發現,它比我想象的要容易:只需在代理類上調用getSuperclass()
即可獲得未加載的原始類。我不確定這是多麼一般,但它似乎工作。
類似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應該給你簡單的對象。
考慮嘗試不需要該對象。也許你可以重新設計應用程序,以便不需要它,例如通過在運行時添加包含所需信息的字段。
雖然我非常喜歡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();
}
}
爲什麼你首先需要這個?該代理擴展了您的基類,因此您可以調用基類實例的每個方法也可以在代理上調用,並返回相同的結果。 –
我正在研究這個關於將hibernate代理對象傳遞給GSON庫的另一個問題。該庫使得一些調用通過實現者傳遞代理'Class',並且稍後代理'Object',我希望能夠開始用'Class'做些事情。 – Flavio