Hibernate вставляет дубликаты в коллекцию @OneToMany

У меня вопрос по Hibernate 3.6.7 и JPA 2.0.

Рассмотрим следующие сущности (некоторые геттеры и сеттеры опущены для краткости):

@Entity
public class Parent {
    @Id
    @GeneratedValue
    private int id;

    @OneToMany(mappedBy="parent")
    private List<Child> children = new LinkedList<Child>();

    @Override
    public boolean equals(Object obj) {
        return id == ((Parent)obj).id;
    }

    @Override
    public int hashCode() {
        return id;
    }
}

@Entity
public class Child {
    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    private Parent parent;

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    @Override
    public boolean equals(Object obj) {
        return id == ((Child)obj).id;
    }

    @Override
    public int hashCode() {
        return id;
    }
}

Теперь рассмотрим этот фрагмент кода:

// persist parent entity in a transaction

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Parent parent = new Parent();
em.persist(parent);
int id = parent.getId();

em.getTransaction().commit();
em.close();

// relate and persist child entity in a new transaction

em = emf.createEntityManager();
em.getTransaction().begin();

parent = em.find(Parent.class, id);
// *: parent.getChildren().size();
Child child = new Child();
child.setParent(parent);
parent.getChildren().add(child);
em.persist(child);

System.out.println(parent.getChildren()); // -> [Child@1, Child@1]

em.getTransaction().commit();
em.close();

Дочерняя сущность ошибочно дважды вставлена ​​в список дочерних сущностей родительской сущности.

При выполнении одного из следующих действий код работает нормально (в списке отсутствуют повторяющиеся записи):

  • удалить атрибут mappedBy в родительском объекте
  • выполнить некоторую операцию чтения из списка детей (например, раскомментируйте строку, помеченную * )

Очевидно, это очень странное поведение. Кроме того, при использовании EclipseLink в качестве поставщика постоянства код работает так, как ожидалось (без дубликатов).

Это ошибка гибернации или я что-то упустил?

Спасибо

19
задан jeha 26 October 2011 в 18:11
поделиться