1

私は単純なクラスで構成された基本的なツリー構造を持っており、単一の親(ルート ノードの場合は null になる可能性があります)と子の順序付きリストに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休止状態マッピング ファイルを使用します。

<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>

ただし、次のコードを使用して、1 つの親内で要素の順序をシャッフルしようとすると:

@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);
}

休止状態でトランザクションをフラッシュすると例外が発生します: ( org.hibernate.exception.ConstraintViolationException ... set parent=null, xorder=null where parent='1' and xid='2'): 基本的に、更新は に設定しようとしますxordernull、これは明らかにデータベース スキーマによって禁止されています。

hbm マッピングで多くの組み合わせを試しましたが、成功しませんでした。休止状態に設定し<list>ても更新が行われない場合、要素を設定してもどちらも役に立ちません。inverse="true"insert="false" update="false"<many-to-one>

マッピングまたはコードのいずれかで、おそらく何かが欠けているとhbm思いますが、それはかなり明白であるべきだと思います...何か考えはありますか?

4

1 に答える 1

0

[アップデート]

以前の答えは正しくありませんでした。制約違反は、親がnullに設定されているためであり、並べ替えによってそれが回避されると思いました。問題はxorderフィールドにあるため、更新する前に、手動でリストを調べて、リスト内の各アイテムについて、各ノードのxorderフィールドがそのアイテム内のそのアイテムの順序と一致することを確認する必要があると思います。リスト。

たとえば、テストリストを取得したときに、3つのノードがあった可能性があります。リストxorder=0のアイテム0の場合、アイテム1にはxorder = 1があり、アイテム2にはxorder=2があります。リスト内のこれらのノードを並べ替える場合(たとえば、0と1を入れ替える場合は、新しいアイテム0のxorder値を1から0に変更し、現在アイテム1になっているノードのxorderが1になっていることを確認する必要があります。

それか、ノードを正しい順序で使用して新しい新しい子リストを作成し、childrenプロパティを新しいリストに設定します。

[前]

のようなことをするのはどうですか

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

これで、必要な並べ替えの変更を行うComparator実装を作成するだけです。これにより、削除時に親がnullに設定されるという制約違反を回避できると思います。

于 2012-10-14T21:01:10.493 に答える