【问题标题】:Hibernate / JPA: duplicates in child collectionHibernate / JPA:子集合中的重复项
【发布时间】:2011-03-15 22:17:39
【问题描述】:

我的数据模型由学校和学生组成。学生拥有他们所属学校的 FK。 我不明白为什么该集合包含重复项,即 Joe、Joe、Mary、Mary、Tom、Tom 等 Hibernate 生成的 SQL 查询是正确的,不会返回重复的。 我可以实施一个 hack 来过滤掉重复项,但我还没有准备好忍受破窗户;) 我试图在下面粘贴相关的代码。非常感谢任何帮助!

// 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;
}

【问题讨论】:

  • 您用来检索对象的具体代码是什么? Hibernate 在某些类型的 HQL 中存在一些已知问题,这些问题会触发这样的重复。

标签: hibernate jpa


【解决方案1】:

我的猜测是您在 School 中有 FetchType.EAGER 或其他映射,这将导致 Hibernate 发出外部连接查询,这将导致列表中出现重复。

将类型切换为 SET 是可行的,因为集合自然会基于相等性进行重复数据删除,因此外部连接查询返回的重复数据会丢失。

Eran Medan 提供更详尽的解释here

【讨论】:

    【解决方案2】:

    从这段代码很难说,但是:

    1. 与集合不同,列表通常允许重复元素(是的,我注意到您说查询不会返回重复项,但我想指出您可能没有使用正确的集合类型)。
    2. 确保无论如何正确实施equals/hashCode(我怀疑这个级别有问题)。

    实际上,你能展示整个映射吗?我不确定为什么在同一个字段上有多个 getter 和 setter。

    【讨论】:

    • equals/hashCode 已正确实现。使用 Set 实际上解决了这个问题,但我认为这是一个 hack。 setStudentsInternal/getStudentsInternal 仅适用于 Hibernate(这些方法未在接口上定义)- 集合被 addStudent、removeStudent 和 getStudents 封装,返回一个不可修改的集合。
    • @Francois: 使用Set 不是黑客,但它可能隐藏了问题的真正原因(这可能就是你称之为黑客的原因)但我不能再说什么如果您没有提供更多代码(确切的映射)。此外,提供表格内容和执行的查询/查询会有所帮助。
    【解决方案3】:

    我认为您正在向集合中添加该对象已经存在的内容。如果没有看到您将内容添加到学校学生集合的代码,则无法确定,但这是我的猜测。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 2011-12-15
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2015-09-13
      • 2013-04-26
      相关资源
      最近更新 更多