7

My data model is made of Schools and Students. Students have a FK to the School they belong to. I do not understand why the collection contains duplicates, i.e. Joe, Joe, Mary, Mary, Tom, Tom, etc The SQL query generated by Hibernate is correct and does not return duplicates. I could implement a hack to filter out duplicates, but I am not ready to live with a broken window yet ;) I have tried to paste the relevant pieces of code below. Any help greatly appreciated!

// 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;
}
Francois
  • 2,289
  • 4
  • 20
  • 21
  • What is the specific code you're using to retrieve the objects? Hibernate has some known issues with certain kinds of HQL which will trigger duplication like this. – Jherico Jul 14 '10 at 19:15

3 Answers3

15

My guess is that you have a FetchType.EAGER or other mapping in School which will cause an outer join query to be issued by Hibernate, which will result in duplicates in the list.

Switching types to SET works because a set naturally de-dupes based on equality, so the duplicates returned by the outer join query are lost.

A much more thorough explanation by Eran Medan available here:

Community
  • 1
  • 1
Derek Troy-West
  • 2,469
  • 1
  • 24
  • 27
1

Hard to say from the piece of code but:

  1. Unlike sets, lists typically allow duplicate elements (yes, I noticed you said the query doesn't return duplicates but I wanted to point out that you're maybe not using the right collection type).
  2. Make sure you implement equals/hashCode properly anyway (I suspect a problem at this level).

Actually, can you show the whole mappings? I'm not sure to understand why you have several getters and setters on the same field.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • equals/hashCode are correctly implemented. Using a Set actually solves the problem, but I consider this as a hack. setStudentsInternal/getStudentsInternal is for Hibernate only (these methods are not defined on the interface) - the collection is encapsulated with addStudent, removeStudent and getStudents that returns an unmodifiable collection. – Francois Jul 14 '10 at 15:52
  • @Francois: Using a `Set` is not a hack but it might be hiding the real cause of the problem (that's maybe why you call it a hack) but I can't say anything more if you don't provide more code (the exact mappings). Also, providing the table content and the query/queries performed would help. – Pascal Thivent Jul 14 '10 at 16:12
0

Me thinks that you're adding things to the Collection that already exist for that object. Can't be sure without seeing the code where you're adding stuff to the School's collection of Students, but that would be my guess.

user919860
  • 3,083
  • 4
  • 19
  • 16