15

JPA 2 には、再帰クエリを実行するためのメカニズムがありますか?

これが私の状況です: 整数フィールド x を含むエンティティ E があります。また、@OneToMany を介してマップされたタイプ E の子を持つこともできます。私がやりたいのは、主キーで E を見つけ、その値 x とそのすべての子孫の x 値を取得することです。単一のクエリでこれを行う方法はありますか?

私は Hibernate 3.5.3 を使用していますが、Hibernate API に明示的な依存関係を持たないようにしたいと考えています。


編集:この項目によると、Hibernate にはこの機能がないか、少なくとも 3 月にはありませんでした。したがって、JPAがそれを持っている可能性は低いようですが、確認したいと思います.

4

4 に答える 4

29

各行にその親への参照が含まれ、同じテーブル内の別の行を参照する単純な隣接モデルを使用すると、JPAとうまく連携しません。これは、JPAがOracleCONNECTBY句またはSQL標準のWITHステートメントを使用したクエリの生成をサポートしていないためです。これらの2つの句のいずれかがないと、隣接モデルを有用にすることは実際には不可能です。

ただし、この問題をモデル化するには、この問題に適用できる他のアプローチがいくつかあります。1つ目は、マテリアライズドパスモデルです。これは、ノードへのフルパスが単一の列にフラット化される場所です。テーブル定義は次のように拡張されます。

CREATE TABLE node (id INTEGER,
                   path VARCHAR, 
                   parent_id INTEGER REFERENCES node(id));

ノードのツリーを挿入するには、次のようになります。

INSERT INTO node VALUES (1, '1', NULL);  -- Root Node
INSERT INTO node VALUES (2, '1.2', 1);   -- 1st Child of '1'
INSERT INTO node VALUES (3, '1.3', 1);   -- 2nd Child of '1'
INSERT INTO node VALUES (4, '1.3.4', 3); -- Child of '3'

したがって、ノード '1'とそのすべての子を取得するには、クエリは次のようになります。

SELECT * FROM node WHERE id = 1 OR path LIKE '1.%';

これをJPAにマップするには、「path」列を永続オブジェクトの属性にするだけです。ただし、「パス」フィールドを最新の状態に保つには、簿記を行う必要があります。JPA/Hibernateはこれを行いません。たとえば、ノードを別の親に移動する場合は、親参照を更新し、新しい親オブジェクトから新しいパス値を決定する必要があります。

もう1つのアプローチは、入れ子集合モデルと呼ばれ、少し複雑です。おそらく、(私が逐語的に追加するのではなく)その創始者によって最もよく説明されています。

ネストされた間隔モデルと呼ばれる3番目のアプローチがありますが、これは実装するストアドプロシージャに大きく依存しています。

この問題のより完全な説明は、The ArtofSQLの第7章で説明されています

于 2010-09-03T21:00:22.727 に答える