在Hibernate中持久循环引用

时间:2014-08-26 20:23:55

标签: mysql hibernate jpa

我有以下情况:

@Entity
class Foo {

    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="parent_id")
    Foo father;

    @OneToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="left_child_id")
    Foo left_child;

    @OneToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="right_child_id")
    Foo right_child;

}

我想坚持其中许多人。在将它们放入列表之前,我设置它们之间的关系,并将它们放在列表中,以便父项始终显示在子项之前。当我坚持下去的时候我会这样做:

tx=session.beginTransaction();
List<Foo> foos=new LinkedList<Foo>();
//Some code here to establish relationships
enter code here
for (Foo foo : foos){
    session.save(foo);
}
tx.commit();

但通过执行此操作,我收到以下错误:错误:无法添加或更新子行:外键约束失败(packageFoo,CONSTRAINT FK_r1pg1dvb3vnuml2e7tw1x2doc FOREIGN KEY( left_child_id)参考Foo ( id`))。

我是否可以坚持保留循环引用?如果可以的话,我想这样做。关于如何坚持这一点的任何想法都是受欢迎的。

1 个答案:

答案 0 :(得分:1)

我尝试了这个,但我没有收到任何错误,这是我的代码:

<强> Foo.java

@Entity 公共课Foo {

@Id
@GeneratedValue
private int id;

@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id")
Foo father;

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "left_child_id")
Foo left_child;

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "right_child_id")
Foo right_child;

// Setters & Getters

}

保存Foo对象的程序:

    Session session = HibernateUtil.getSessionFactory().openSession();
    session.getTransaction().begin();

    Foo father = new Foo();
    Foo leftChild = new Foo();
    Foo rightChild = new Foo();

    Foo foo = new Foo();
    foo.setFather(father);
    foo.setLeft_child(leftChild);
    foo.setRight_child(rightChild);

    session.persist(foo);
    session.getTransaction().commit();

数据库中的数据:

SQL> select * from foo;

        ID  PARENT_ID LEFT_CHILD_ID RIGHT_CHILD_ID
---------- ---------- ------------- --------------
         2
         3
         4
         1          2             3              4

现在,如果我尝试保存多个Foo个对象,它们也会正确保存:

private static void saveElements() {
    Session session = HibernateUtil.getSessionFactory().openSession();
    session.getTransaction().begin();

    Foo foo1 = getFooObject();
    Foo foo2 = getFooObject();

    Foo foo = new Foo();
    Foo father = new Foo();
    Foo leftChild = new Foo();
    Foo rightChild = new Foo();

    foo.setFather(father);
    foo.setLeft_child(leftChild);
    foo.setRight_child(rightChild);

    foo.setFather(foo1.getFather());
    foo.setLeft_child(foo2.getFather());

    session.persist(foo1);
    session.persist(foo2);
    session.persist(foo);
    session.getTransaction().commit();

}

private static Foo getFooObject() {
    Foo foo = new Foo();
    Foo father = new Foo();
    Foo leftChild = new Foo();
    Foo rightChild = new Foo();

    foo.setFather(father);
    foo.setLeft_child(leftChild);
    foo.setRight_child(rightChild);
    return foo;
}



SQL> select * from foo;

        ID  PARENT_ID LEFT_CHILD_ID RIGHT_CHILD_ID
---------- ---------- ------------- --------------
         2
         3
         4
         1          2             3              4
         6
         7
         8
         5          6             7              8
        10
         9          2             6             10

10 rows selected.