2014-01-25 48 views
0

我正在嘗試爲以下情況找到最佳解決方案:我有一個必須進行代理的實體A.問題是,當我簡單地通過擴展類A來創建抽象代理將其所有行爲委託給包裝的實體時,我最終會從該實體繼承大量未使用的字段。但至少它不會改變持久性的工作方式。實體代理時的代理模式?

爲了不這樣做,我創建了一個抽象超類,它只包含抽象方法(public和protected,這就是爲什麼我沒有使用接口)並且使它成爲Entity和所有代理。這個解決方案似乎是最好的,但是它在持久性方面遇到了很多麻煩......

我想依賴我的應用程序層中的抽象超類(因爲它不區分代理A和非-proxied -A),但是然後Hibernate不會讓我 - 實體實例不能與抽象類有關係,因爲它不被持久化上下文知道。當然,我可以貶低實體類,但它擊敗了目的......

有沒有辦法讓Hibernate降低實體本身的實體?我的意思是,我可以在任何地方使用抽象類,但休眠會知道它的真正的實體類...

public abstract class AbstractA { 

    public abstract void doSomethingOnA(); 

} 


@Entity 
public class EntityA extends AbstractA { 

    @Id 
    private Long id; 

    @Column(name="column_in_a") 
    private SomethingA somethingA; 

    @Override 
    public void doSomethingOnA() { 
     somethingA.doSomething(); 
    } 

} 

public class ProxiedA extends AbstractA { 

    private AbstractA wrappee; 

    @Override 
    public void doSomethingOnA() { 
     doSomethingFirst(); 
     wrappee.doSomethingOnA(); 
    } 

} 

問題是,我想使用AbstractA代替EntityA也當涉及到持久性。問題是當另一個實體聲明一個AbstractA類型的字段時,Hibernate將會失敗。我知道爲什麼,問題是如何處理它?

謝謝!

回答

1

我傾向於做的是創建一個接口,例如用戶。然後我將有一個POJO調用UserBean和一個實體調用UserEntity,它們都實現了該接口。然後,您可以執行以下兩項操作之一:在實體中擁有一個構造函數,並使用該bean和createBean方法從實體創建bean。我沒有在bean類中爲實體構造一個構造函數,因爲在我的場景中,我有一個沒有JPA訪問權的圖層,所以這些bean不能具有實體的任何知識。

Hibernate或任何JPA提供程序會知道它何時會得到一個真正的UserEntity,並且如果您不小心將其發送給UserBean,它將會正確地投訴。很多時候我甚至沒有實現相同的接口。這樣我就可以強制執行,我不會在持久性邊界上意外發送UserEntity而不是UserBean。

再次,我可能會誤解你的問題,因爲代名詞有很多含義。例如,您可能正在談論延遲加載代理作爲實體的屬性。或者你可能正在談論一個遠程代理。

1

沒有看到代碼,理解你所描述的內容是一個挑戰。但通過你的描述看完之後,這裏有一些想法:

  • 從面向對象的角度來看,如果延長EntityA導致許多不必要的成員,你的子類不覺得這是一個真正的子類。子類的一個實例實際上應該是EntityA的一個實例,它實際上只專注於行爲並可能擴展父類的成員變量。
  • 從持久性的角度來看,如果你的子類不會使用許多組成EntityA的字段,那麼你面臨的問題是「不需要」的關係屬性可能需要特殊處理或某種解決方法編碼你的子類對象。

再次,這是很難做到無代碼審查具體,但它聽起來像是你可能要由成員變量和操作,這是共同的EntityA和你的抽象類重構到一個共同的開始父類。然後可以對父類進行註釋以包含映射到列的真實體屬性。從那裏,你可以使用簡單的Java繼承和Hibernate的繼承模式之一來完成您的實現:

  • Table per concrete subclass,這可能在Hibernate中使用XML映射一個<class>標籤來定義,不需要額外的處理處理多態,因爲Hibernate將掃描持久化類並瞭解超類或接口。
  • Table per concrete subclass with unions,這可能在Hibernate中使用XML映射一個<union-subclass>標籤來定義,效果最好的時候,你不需要多態查詢和使用,可能會涉及非持久性接口(UNION基)查詢(這聽起來像它可能是你的情況)。
  • Table per concrete subclass with joins,這可能在Hibernate中使用XML映射一個<joined-subclass>標籤來定義,是最好的,如果你想(或必須使用)一個完全規範化的數據庫架構。
  • Table per class hierarchy,這可能在Hibernate中使用XML映射一個<subclass>標籤來定義的,是最簡單,因爲所有的子類映射到一個表,表現最好,但如果唯一列的定義才起作用子類可能是NULL
+0

事情是我提到的那些代理不會被持久化。它們纏繞在沒有任何兄弟實體的單個實體中。請看我更新的問題。 – kboom