2011-07-21 64 views
1

我想在hibernate中映射樹,但由於循環引用(關係不是雙向的),持久化會導致異常。休眠中的循環關係

class Node { 
    @ManyToOne 
    Node parent; 

    @OneToOne 
    Node leftChild; 

    @OneToOne 
    Node rightChild; 
} 

節點N引用它的左子L,而子L又引用N作爲其父。而且,節點N引用它的右側子節點R,子節點R再次再次引用N作爲父節點。但是,我不能使關係成雙向的,因爲父母將是leftChild和rightChild的逆向。什麼是使這個模型可持續的最佳方式?

問候, 約亨

回答

1

我沒有看到這個問題:

@Entity 
class Node { 
    @Id @GeneratedValue 
    private int id; 
    private String name; 

    @ManyToOne(cascade = CascadeType.ALL) 
    Node parent; 

    @OneToOne(cascade = CascadeType.ALL) 
    Node leftChild; 

    @OneToOne(cascade = CascadeType.ALL) 
    Node rightChild; 

    Node() {} 

    public Node(String name) { 
     this.name = name; 
    } 
    // omitted getters and setters for brevity 
} 

public static void main(String[] args) { 
    SessionFactory sessionFactory = new Configuration() 
        .addAnnotatedClass(Node.class) 
        .setProperty("hibernate.connection.url", 
         "jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1") 
        .setProperty("hibernate.hbm2ddl.auto", "create") 
        .buildSessionFactory(); 
    Session session = sessionFactory.openSession(); 
    Transaction transaction = session.beginTransaction(); 
    Node a = new Node("A"); 
    Node b = new Node("B"); 
    Node c = new Node("C"); 
    Node d = new Node("D"); 
    Node e = new Node("E"); 
    a.setLeftChild(b); 
    b.setParent(a); 
    a.setRightChild(c); 
    c.setParent(a); 
    b.setLeftChild(d); 
    d.setParent(b); 
    b.setRightChild(e); 
    e.setParent(b); 
    System.out.println("Before saving:"); 
    print(a, 1); 
    Serializable rootNodeId = session.save(a); 
    transaction.commit(); 
    session.close(); 

    session = sessionFactory.openSession(); 
    Node root = (Node) session.load(Node.class, rootNodeId); 
    System.out.println("Freshly loaded:"); 
    print(root, 1); 
    session.close(); 
} 

private static void print(Node node, int depth) { 
    if (node == null) { return; } 
    System.out.format("%" + depth + "s\n", node); 
    print(node.getLeftChild(), depth + 1); 
    print(node.getRightChild(), depth + 1); 
} 
+0

工程與Hibernate 4.3.11。謝謝! – Jochen

0

有沒有辦法讓Hibernate來區分左右的孩子在你的榜樣。無論Hibernate如何,在數據庫中有兩行可以引用父對象,你如何區分左對齊和右對齊?因此,如果在同一個表中有多個引用父項的條目,則實際上從父項到子項節點有OneToMany。因此,我建議您將它建模爲@OneToMany。然後,如有必要,通過一些額外的邏輯提供一些瞬時吸氣劑,以便在兒童列表中區分左側兒童與右側兒童。