0

SINGLE_TABLE 戦略を使用した JPA エンティティの継承に関する問題。getter @Discriminator では、継承の範囲を縮小します。

私は次の構造を持っています:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type")
@DiscriminatorValue("A")
class A {
...
}

@Entity
@DiscriminatorValue("B")
class B extends A {
...
}

@Entity
@DiscriminatorValue("C")
class C extends B {
...
}

@Entity
class Something{
@ManyToMany // blah blah
private List<B> listB; // getters and setters
}

問題は次のとおりです。クラス C のオブジェクトがあります (継承 C も B であると仮定します)。私がやっているとき:

Something s = Something.findById(11); // Here is listB with elements of type C and B
List<B> listB = s.getListB();

クラス B のオブジェクトのみをフェッチし、C はフェッチしません。ただし、C は B を拡張するため、リストにも含まれている必要があります。Getter は次のようなクエリを作成します。

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type = ? 
[params=(long) 205, (String) B]

問題は、このゲッター (Something.getListB) がこのリストを (ディスクリミネーター B によって) クラス B のみに縮小することです。この結果、オブジェクト クラス C はリストにありません。厳密な型「t1.type = B」を示す @Discriminator が原因です。「t1.type IN (B,C)」のようなセット/リストをそこに置くことはできません。

カスタム JPQL クエリは、さまざまな方法で構築されます。

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type IN (?, ?) 
[params=(long) 205, (String) B, (String) C]

そして彼らは彼らがすべきように働きます。しかし、ゲッターはどうですか?

興味深いのは、Something クラスを B クラスから A クラス (すべてのベース) に変更すると、次のようになるという事実です。// ゲッターとセッター }

これは問題を解決します。クエリのゲッターで:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? 
[params=(long) 205]

「AND t1.type = ?」が消えます。動作しますが、「現実世界のオブジェクト」から「ORM エンティティ」へのマッピングを妨げます。その解決策は変化し、その抽象化を悪化させます。それはエレガントな解決策ではありません。

質問:

どうすればこの問題を解決できますか?

getter でカスタム JPQL クエリを使用できますか?

そのゲッターに B および C オブジェクトを取得させる方法は?

リストをリストに変更する代わりに、別の提案はありますか???

4

1 に答える 1

0

どのJPAプロバイダーを使用していますか?バグのように聞こえます。これはEclipseLinkで機能するはずです。

于 2012-02-02T14:07:14.633 に答える