2012-10-14 55 views
1

我有一個簡單Node類組成的基本樹結構,連接雙向它是單親(可爲空的根節點)和兒童的有序列表:休眠:在雙向洗牌子節點有序樹

public class Node { 
    private Integer xid; 
    private Node parent; 
    private List<Node> children; 
    // getters and setters... 
} 

我這個映射使用Hibernate以下簡單的數據庫表:

> select * from node; 
xid | parent | xorder 
-----+--------+-------- 
    1 | NULL |  0 
    2 |  1 |  0 
    3 |  1 |  1 
    4 |  1 |  2 
(4 rows) 

使用以下.hbm Hibernate映射文件:

<class name="Node" table="node"> 
    <id name="xid" type="int"> 
     <generator class="native" /> 
    </id> 
    <many-to-one name="parent" /> 
    <list name="children" table="node"> 
     <key column="parent" /> 
     <list-index column="xorder" /> 
     <one-to-many class="Node" /> 
    </list> 
</class> 

然而,當我嘗試使用下面的代碼洗牌元素父母一方內訂購:

@Transactional 
public void testNode() { 
    Node parent = (Node) getSession().get(Node.class, 1); 
    Node child0 = parent.getChildren().remove(0); 
    parent.getChildren().add(1, child0); // Swap first and second child 
    getSession().update(parent); 
} 

我得到當Hibernate刷新事務異常:(org.hibernate.exception.ConstraintViolationException ... set parent=null, xorder=null where parent='1' and xid='2'):基本更新嘗試將xorder設置爲null,這顯然是數據庫架構禁止的。

我在hbm映射上嘗試了很多組合,但沒有成功。當我將<list>設置爲inverse="true"休眠不會進行任何更新時,在<many-to-one>元素上設置insert="false" update="false"也不會有幫助。

我可能會錯過這裏,無論是在hbm映射或在我的代碼,我的感覺是,它應該是非常明顯的......任何想法?

回答

0

[更新]

以前的答案不正確。我認爲違反約束條件是因爲父母被設置爲空,並且排序會避免這種情況。由於問題在於xorder字段,因此我認爲在更新之前,您需要手動檢查列表並確保對於列表中的每個項目,每個節點的xorder字段與項目中的項目順序相匹配名單。

例如,當您拉出測試列表時,您可能有3個節點。對於列表xorder = 0中的項目0,項目1具有xorder = 1,項目2具有xorder = 2。如果您重新排列列表中的這些節點(例如交換0和1,則應確保將新項目0 xorder的值從1更改爲0,並且現在項目1的節點的xorder應爲1)。

要麼或創建以正確的順序節點新新兒童名單和屬性設置的孩子到新名單。

[上一頁]

如何做這樣的事情

Collections.sort(parent.getChildren(), new MyComparator()); 

現在你所要做的就是寫一個Comparat或實現,使排序變化你想要的。我認爲這將避免違反約束的情況下父母在刪除時被設置爲空。

+0

那麼,這裏的問題是,我不能輕鬆使用比較器,洗牌是由重新排列元素的用戶完成的。無論如何,奇怪的是,移動它後,子元素仍然具有父元素集,所以我認爲問題與此無關。 –

+0

查看更新。還有一個嘗試:) –

+0

嗯,這裏的訣竅是我沒有訪問我的java類中的'xorder'字段:它由Hibernate接管(請參閱'list-index'定義),這是它的一個附加值。事實上,我已經有一個工作解決方案去除'list-index',在java類中添加'xorder'字段並且自己照顧索引管理,但是我想讓hibernate處理這個問題,這是方法簡單。 –