2011-12-07 91 views
6

我偶然發現了一個非常惱人的情況:我使用Hibernate & Spring作爲我的應用程序的後端,並且似乎在某些情況下,與特定關係的實體實體不是從數據庫中作爲普通實體對象獲取,而是作爲Javassist類型獲取。例如:獲取Javassist類型而不是實際的Hibernate實體類型

我有以下關係活動實體:

@Entity 
@Table(name = "campaign") 
public class Campaign implements Serializable { 
    [..] 
    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = { 
     "campaign_id", "dealer_id" }), name = "campaign_has_dealer", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "dealer_id", nullable = false) }) 
    private List<Dealer> dealers = new ArrayList<Dealer>(); 

@ManyToMany 
// (fetch = FetchType.LAZY) 
@JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = { 
     "campaign_id", "sales_area_id" }), name = "campaign_has_sales_area", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "sales_area_id", nullable = false) }) 
private List<SalesArea> salesAreas = new ArrayList<SalesArea>(); 
} 

在檢索連接到這個活動中salesAreas,我得到SalesArea列表_ $$ _ javassist_56,而對於經銷商,我得到正常Hibernate實體。由於客戶端部分基於GWT,因此我們使用RequestFactory來檢索內容。我最初認爲這是代理,定位器等問題,但我已經在檢索這些服務的服務中設置了一個斷點,並且在選擇它們後直接選擇它們是Javassist對象。似乎即使刪除FetchType.LAZY註釋(儘管絕對不是一個理想的解決方案),也會發生同樣的情況。這也發生在其他類型的關係中,而不僅僅是@ManyToMany。

我們使用GWT 2.3,Spring 3,Hibernate 3.6.3和JPA 2.0進行註釋。

任何建議,將不勝感激。

在此先感謝

+2

FetchType.LAZY是JPA默認值。除非您指定FetchType.EAGER,否則它不會執行任何操作。 – viktor

回答

4

至於我可以看到,您遇到的最大的問題是沒有這麼多的關聯獲取類型,而是被代理的類型不與RequestFactory很好地工作。

是的,它可以通過改變獲取策略來解決,但這聽起來像是一個弱解決方案,可能會破壞奇怪的情況。

我不記得如何解決它,但我確實記得,並且據我所知,ServiceLayerDecorator類中有一個擴展點。基本上你會檢查你要返回的對象是否是一個Hibernate代理(檢查Hibernate和HibernateProxy類),然後在ServiceLayerDecorator中返回非代理類型。 (http://code.google.com/p/google-web-toolkit/issues/detail?id=6767

至於你的抓取策略,我主要推薦@BatchSize(N),其中N很大(也許是1000),但這是一個獨立的主題。

祝你好運!

+1

非常感謝,解決方案是實現一個自定義ServiceLayerDecorator並覆蓋getProperty方法,正如有人在您發送的鏈接中所說的那樣。它現在有效! :) – AndaP

0

有了Hibernate的代理模型,現在使用Javassist來幫助避免傳統Hibernate運行時反射操作的速度變慢,事情永遠不會像使用完整字節碼增強解決方案(如JDO實現)的乾淨,直觀的體驗那樣優雅例如DataNucleus)享受。

個人而言,我可以永遠也看不到感持續(原諒雙關語)的解決方案,導致這麼多的問題,並填寫有關斷碼的問題,需要奇怪,不直觀的解決方法,但仍人做網頁...

但是,回到問題:如果您使用JPA,您的問題的一個解決方案是使用DataNucleus/JPA,它帶來了DataNucleus/JDO的許多好處(乾淨的底層實現 - 沒有代理,沒有Javassist類等。 ,)在遵循JPA的實現中 - 即,您不需要更改現有的源代碼即可開始使用它。

1

如果您調用靜態方法: HibernateProxyHelper。getClassWithoutInitializingProxy(實體); 如果代理實體沒有被代理,你將得到代理實體的類和類本身。

相關問題