2011-06-10 62 views
3

我需要一個實體與其他實體的兩個列表關聯 - 含有相同類型的實體兩份名單。它看起來是這樣的:休眠:多個關聯到同一個類

@Entity 
public class Course { 
    private List<Test> preTests; 
    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = 「course」) 
    @OrderBy("testNumber") 
    public List<Test> getPreTests() { 
     return preTests; 
    } 

    public void setPreTests(List<Test> preTests) { 
     this. preTests = preTests; 
    } 

    private List<Test> postTests; 
    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = 「course」) 
    @OrderBy("testNumber") 
    public List<Test> getPostTests() { 
     return postTests; 
    } 

    public void setPostTests(List<Test> postTests) { 
     this. postTests = postTests; 
    } 
} 

現在,我還沒有費心去嘗試這種本身因爲它似乎很明顯,休眠就沒有辦法區分哪些Tests進入preTests併爲postTests。糾正我,如果我錯了,但它的唯一信息是與在Test表的外鍵指向Course記錄工作,無論是前,後測試將在同一Course點。 我的下一個想法是創建的Test明確PreTestPostTest子類,並有一個List<PreTest>和一個List<PostTest>,但導致了臭名昭著的「的mappedBy引用一個未知目標實體屬性:課程」的問題,這在休眠要求的人 - 爲那些令我感到驚訝的原因 - 是通過設計來實現的,因此不可能消失。

我現在的想法是使用單獨的連接表來保存兩個協會。我沒有看到爲什麼這不起作用的理由。它也適合我希望將實體定義中的所有顯式SQL(甚至HQL)都保留下來,並抵制強制創建奇怪的組合鍵或者編寫僅反映持久性框架而不是我的對象設計怪癖的代碼。

不過,之前我承諾此過程中,我問任何你是否有一個清晰的解決方案或在這裏我的推理缺陷知道。

在此先感謝。

邁克爾

回答

1

我不知道這是不是一個很好的主意或沒有,但你可以包括你的關聯映射一個

@org.hibernate.annotations.Where 

註釋,並在您的測試表使用一個鑑別列,因此您可以在加載測試實例時通過Post測試告訴Pre。

+0

我給你一個給予好評,因爲它肯定是一個合理的答案,但它屬於下我的願望,以保持實際的SQL/HQL出來的東西,所以我更喜歡我的解決方案,甚至在一個額外的費用幾張桌子和幾乎沒有效率的查詢。 – Michael 2011-06-11 18:20:47

0

一種選擇是繼承映射,它聽起來像你開始這樣做,但沒有去所有的方式的Table per class hierarchy方法。

另一種選擇是,如另有說明,否則使用@Where annotation

我經常用於類似情況的第三個選項是爲與課程相關的所有測試映射單個集合,然後添加幫助器方法以在您想要使用pre或post時處理所需的子集試驗。示例代碼:

@Entity 
    public class Course { 

    private List<Text> tests; 

    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = 「course」) 
    @OrderBy("testNumber") 
    public List<Test> getTests() { 
     return tests; 
    } 

    public List<Test> getPreTests() { 
     List<Test> preTests = new ArrayList<Test>(); 
     for (Test test : preTests) { 
      if (test.isPreTest()) { 
       preTests.add(test); 
      } 
     } 
     return preTests; 
    } 


    public List<Test> getPostTests() { 
     List<Test> postTests = new ArrayList<Test>(); 
     for (Test test : postTests) { 
      if (test.isPostTest()) { 
       postTests.add(test); 
      } 
     } 
     return postTests; 
    } 
+0

謝謝,Stevi,但我不知道在哪裏「每個類分層結構表」的方法下車的 - 這就是我的設置繼承,但我還是得到了「未知目標實體屬性」的錯誤。除非也許你是在暗示我將'course'字段放到子類中,否則就是擺弄類層次結構來僞造Hibernate呢?另外兩個建議是合理的,但不雅觀 - IMO稍微比我少建議優雅。 – Michael 2011-06-11 18:27:31

+0

我不確定基於我在你的問題中看到的爲什麼你會得到「未知的目標實體屬性」,所以我不能說那個。我已經爲第三個選項添加了示例代碼。不,這不是最優雅的解決方案,但我傾向於在處理Hibernate方面非常務實。 – 2011-06-13 15:58:21