2010-07-14 5 views
5

Моя модель данных состоит из школ и студентов. У студентов есть FK в Школу, в которой они принадлежат. Я не понимаю, почему коллекция содержит дубликаты, т. Е. Джо, Джо, Мэри, Мэри, Том, Том и т. Д. SQL-запрос, сгенерированный Hibernate, является правильным и не возвращает дубликатов. Я мог бы реализовать хак, чтобы отфильтровать дубликаты, но я еще не готов жить с разбитым окном;) Я попытался вставить соответствующие фрагменты кода ниже. Любая помощь очень ценится!Hibernate/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

ответ

1

Трудно сказать, из куска кода, но:

  1. В отличие от наборов, списки обычно позволяют повторяющиеся элементы (да, я заметил, что ты сказал, что запрос не возвращает дубликатов, но я хотел бы отметить что вы, возможно, не используете правильный тип коллекции).
  2. Убедитесь, что вы правильно использовали equals/hashCode (я подозреваю, что проблема на этом уровне).

Собственно, вы можете показать все сопоставления? Я не знаю, почему у вас есть несколько геттеров и сеттеров в одном поле.

+0

equals/hashCode правильно реализованы. Использование набора действительно решает проблему, но я считаю это взломом. setStudentsInternal/getStudentsInternal только для Hibernate (эти методы не определены на интерфейсе) - коллекция инкапсулирована с помощью addStudent, removeStudent и getStudents, которая возвращает немодифицируемую коллекцию. – Francois

+0

@Francois: Использование 'Set' не является взломом, но может скрывать реальную причину проблемы (возможно, поэтому вы называете это взломом), но я не могу сказать ничего больше, если вы не предоставляете больше кода (точные отображения). Кроме того, предоставление содержимого таблицы и выполненных запросов/запросов могло бы помочь. –

13

Я предполагаю, что у вас есть FetchType.EAGER или другое сопоставление в школе, которое вызовет запрос внешнего соединения Hibernate, что приведет к дублированию в списке.

Переключение типов в SET выполняется, потому что набор естественным образом деактивируется на основе равенства, поэтому дубликаты, возвращаемые внешним запросом объединения, теряются.

Гораздо более подробное объяснение по Eran Medan доступной here:

0

Me думает, что вы добавляете вещи в коллекции, которые уже существуют для этого объекта. Не может быть уверен, не видя кода, в котором вы добавляете материал в коллекцию Студентов, но это было бы моей догадкой.

Смежные вопросы