2012-11-24 41 views
5

我使用Hibernate與代理,並且我得到屬於類的對象,如test.DBUser$$EnhancerByCGLIB$$40e99a2d如何從代理類中檢索代理類?

是否有Hibernate方法從代理的中檢索基類(在這種情況下爲test.DBUser)?我知道Hibernate.getClass(),但它需要Object,而我正在尋找一種方法,它需要輸入Class

+1

爲什麼你首先需要這個?該代理擴展了您的基類,因此您可以調用基類實例的每個方法也可以在代理上調用,並返回相同的結果。 –

+0

我正在研究這個關於將hibernate代理對象傳遞給GSON庫的另一個問題。該庫使得一些調用通過實現者傳遞代理'Class',並且稍後代理'Object',我希望能夠開始用'Class'做些事情。 – Flavio

回答

3

我發現,它比我想象的要容易:只需在代理類上調用getSuperclass()即可獲得未加載的原始類。我不確定這是多麼一般,但它似乎工作。

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 } 

這將是便宜很多很多工作要做,靜態地圖查找,以獲得真正的類,但休眠去一路懶初始化得到實現類。

0

沒有這樣的方法。您需要自己編寫一個助手類,以便從代理內部檢索包裝對象以及類信息。如果您只需要給定場景中的對象,請嘗試刪除所有延遲加載。然後Hibernate應該給你簡單的對象。

考慮嘗試不需要該對象。也許你可以重新設計應用程序,以便不需要它,例如通過在運行時添加包含所需信息的字段。

3

雖然我非常喜歡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(); 
    } 
}