JPA - 无效的重复插入

时间:2012-06-25 02:32:38

标签: java hibernate jpa

这是我的代码

@Entity
class Parent extends Person {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "father")
    private List<Child> children;

    // ...

    public void addChild(Child c) {
        children.add(c);
    }

}

@Entity
class Child extends Person {
    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "id")
    private Parent father;

    public Child() {
        this(NoParent.getInstance());//
    }

    public Child(Parent p) {
        super();
        setParent(p);
    }

    // ...
}

@MappedSuperclass
class Person {
    @Id
    private Integer id;
    private String name;
}

class MyParentService {

    public void addChild(String name, Parent parent) {
        Child c = new Child(parent);
        c.setName(name);
        parent.addChild(c);

        em.getTransaction.begin();
        em.merge(parent);
        em.getTransaction.commit();// Here two children with same name but different ids are created ...
    }
}    

每次运行时,都会有两个孩子加入数据库,而我只想要一个! 我做错了什么?

Java 6
JPA 2
Hibernate 3.6.8.GA

2 个答案:

答案 0 :(得分:2)

您是否有机会在父母之后坚持孩子?此外,最佳做法是仅在关系的拥有方(在一个方法中同时使用parent.addChild和child.setParent)管理对象的链接,但这在您的情况下似乎并不重要,因为在“合并”发生时,对象被正确链接。如果这些都不起作用,那么您可能会遇到这个问题:https://hibernate.onjira.com/browse/HHH-5855

答案 1 :(得分:1)

我阅读了Hibernate文档,这篇文章真的令人困惑,并没有给我太多帮助。

注意,我发现ObjectDB最近面临并修复了the exact same bug。 (Hibernate家伙你为什么要等这么久?)

尽管如此,我提出了解决方案:

第1步:
  创建一个全新的子节点(即处于分离状态)并调用其setParent方法链接到其父节点。

第2步:
  坚持这个孩子。

第3步:
  根据需要对子进行更改,稍后再合并。

解决方案非常优雅,但它有效! 接下来,您将获取父对象,它将手动将之前的子对象链接到它。