2010-07-14 111 views
5

我的數據模型由學校和學生組成。學生對他們所屬的學校有FK。 我不明白爲什麼集合包含重複項,即Joe,Joe,Mary,Mary,Tom,Tom等 由Hibernate生成的SQL查詢是正確的,並且不會返回重複項。 我可以實現一個黑客過濾出重複,但我還沒有準備好與一個破碎的窗戶生活;) 我試圖粘貼下面的相關代碼段。任何幫助非常感謝!休眠/ JPA:子集合中的副本

// SchoolJpa 

@OneToMany (
    mappedBy = "school", 
    targetEntity = StudentJpa.class, 
    fetch = FetchType.LAZY, 
    cascade = CascadeType.ALL 
) 
@Override 
public List<Student> getStudentsInternal() { 
    return super.getStudentsInternal(); 
} 

// SchoolImpl 

private List<Student> students = new ArrayList<Student>(); 

public List<Student> getStudents() { 
    return Collections.unmodifiableList(students); 
} 

public List<Student> getStudentsInternal() { 
    return students; 
} 

public void setStudentsInternal(List<Students> students) { 
    this.students = students; 
} 
+0

您用於檢索對象的特定代碼是什麼? Hibernate有一些已知的問題,某些類型的HQL會觸發像這樣的重複。 – Jherico 2010-07-14 19:15:54

回答

1

難以從一段代碼,但說:

  1. set不同,通常會列出允許重複的元素(是的,我注意到你說的查詢不返回重複,但我想指出你可能沒有使用正確的集合類型)。
  2. 無論如何,請務必正確實施equals/hashCode(我懷疑這個級別存在問題)。

其實,你能展示整個映射嗎?我不知道爲什麼你在同一個領域有幾個getter和setter。

+0

equals/hashCode已正確實施。使用Set實際上解決了這個問題,但我認爲這是一個黑客。 setStudentsInternal/getStudentsInternal僅用於Hibernate(這些方法未在接口上定義) - 集合使用addStudent,removeStudent和getStudents封裝,它返回一個不可修改的集合。 – Francois 2010-07-14 15:52:57

+0

@Francois:使用Set不是黑客,但它可能隱藏了問題的真正原因(這也許是爲什麼你稱它爲黑客),但如果你不提供更多的代碼,我不能再多說什麼了(確切的映射)。此外,提供表格內容和執行的查詢/查詢將有所幫助。 – 2010-07-14 16:12:32

13

我的猜測是你在學校有一個FetchType.EAGER或其他映射,這將導致外部連接查詢由Hibernate發出,這將導致列表中出現重複。

將類型切換到SET的工作原理是因爲一個集合基於等同性自然去除,因此外部連接查詢返回的重複項會丟失。

一個更詳盡的解釋由Eran Medan可用here

0

我認爲您要添加的東西已經存在該對象的集合。如果沒有看到代碼添加到學校的學生集合中的代碼,這是不確定的,但這是我的猜測。