2010-07-14 108 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

我认为您要添加的东西已经存在该对象的集合。如果没有看到代码添加到学校的学生集合中的代码,这是不确定的,但这是我的猜测。