2

次の継承階層があります。

@Entity
@Table(FRUIT)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColum(name="FRUIT_TYPE",discriminatorType=STRING)
public class Fruit {
..
@Id
private FruitId id;
...
}

@DiscriminatorValue("APPLE")
public class Apple extends Fruit {
...
@ManyToOne
private FruitBowl bowl; //this association is only present in the subclass

...
}

class FruitBowl .. {
...
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "bowl")
    @IndexColumn(name="POSITION",base = 1) 
        List<Apple> apples;
...

を実行すると、選択クエリsession.load(Apple.class,...)に追加されます。FRUIT_TYPE = 'APPLE'しかし、(Apple と 1:m の関係にある) FruitBowl で select を実行すると、Apple の select クエリには が含まれませんFRUIT_TYPE = 'APPLE'。なぜこれが起こるのですか?問題を修正するにはどうすればよいですか?

クエリ -- FruitBowl のクエリ

select fruitbowl0_.BOWL_ID as BOWL1_1_0_ from FRUITBOWL fruitbowl0_ where fruitbowl0_.BOWL_ID=? 

-- リンゴを取得するための Fruit のクエリ (fruit_type ='A' のレコード) -- ただし、その条件は含まれていません

select apples0_.ENTITY_ID as ENTITY3_1_, apples0_.POS as POS1_, apples0_.POS as POS0_0_, apples0_.ENTITY_ID as ENTITY3_0_0_, apples0_.COLOR as COLOR0_0_ from FRUIT apples0_ where apples0_.ENTITY_ID=?
4

2 に答える 2

4

@DiscriminatorOptions(force=true)この関係をクエリするときに hibernate にデスクリミネーターを使用させる「フルーツ」クラスを追加できます。

これはデフォルトで期待されるもののように思えますが、そうでないのにはパフォーマンス上の理由があるのか​​もしれません。

于 2012-10-17T03:54:43.180 に答える
0

(マッピング/SQLクエリ/質問に投稿されたサンプルデータ/コメントに基づいて編集)。

マッピングFruitBowlは、 のコレクションを含むことを指定しますAppleAppleしたがって、Hibernate はインスタンスのみを返すことができることを事前に知っているため、そのコレクションのローダークエリに識別子値条件を追加しません。

投稿した SQL クエリはまさにそれを行います - FruitBowlID でロードし、その後そのインスタンスapplesのコレクションをロードします。FruitBowl問題は、投稿したデータにあります。

fruit_type entity_id 位置の色
     A 1 1 ホワイト
     B 1 2 青

Fruitwith discriminator value B- Banana?の別のインスタンスがあります。:-) - 同じentity_idであるため、コレクション読み込みクエリの一部として取得されます。ここでの質問は、そもそもどのように挿入されたのですか? 次の 2 つのシナリオが考えられます。

  1. BananaのサブクラスですApple。その場合、すべてが正しく、applesコレクションの一部として返されます。
  2. テスト目的で上記のデータを手動で挿入しました。このデータは、Hibernate の観点からは違法です。Hibernate 自体によって挿入されることはありませ。これは、あなたが見ている行動につながります。Banana行を取り除くか、その行を削除する必要がありますentity_id(したがって、applesコレクションから削除します)。

一般に、オブジェクト階層とコレクション要素を同じテーブルに混在させることはお勧めできません。階層を「サブクラスごとのテーブル」として再マッピングするか、applesコレクションを使用してマッピングすることを検討@JoinTableしてください。後者の場合、単方向になることに注意してください。

于 2009-11-09T17:53:40.640 に答える