4

次のようなシナリオがあります。

@Entity
@Table(name = "ANIMAL")
@Inheritance(strategy = InheritanceType.JOINED)

public class Animal implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_ANIMAL")
    @SequenceGenerator(name = "S_ANIMAL", sequenceName = "S_ANIMAL", allocationSize = 1)
    public int getNumero() {
        return numero;
    }

    public void setNumero(int numero) {
        this.numero = numero;
    }
        .
        .
        .
}

サブクラスとして:

@Entity
@Table(name = "DOG")
public class Dog extends Animal {

    private static final long serialVersionUID = -7341592543130659641L;
        .
        .
        .
}

次のようなJPASelectステートメントがあります。

SELECT a FROM Animal a;

Hibernate3.3.1を使用しています

私が見ることができるように、フレームワークは左外部結合のインスタンスを取得しAnimal、またそれを使用します。Dog

「パーツ」のみを選択する方法はありAnimalますか?つまり、前のものSelectはすべてのAnimals、sだけでAnimalsではないものDog、およびsであるものを取得しDogます。

全部欲しいのですが、Dogsの場合は「動物の部分」だけを取り出したいです。

私は見つけました@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT) が、私が見ることができるように、これは動物がそうでない場合にのみ機能し@Entityます。

どうもありがとう。

4

2 に答える 2

3

簡単な答え:あなたが説明する動作はJPA標準に準拠しています。スーパークラスのみを取得するようにJPAプロバイダーを制限するJPA標準の方法はありません。

プロバイダーは、クエリ実装ロジックを選択して、機能、一貫性、およびパフォーマンスを実現できます。エンティティの注釈を尊重し、クエリで要求された情報を返す限り、すべて問題ありません。Dogへの外部結合は、関係のないプライベートな実装の詳細と考えてください。プロバイダーは、パフォーマンスと一貫性を支援するために外部結合をコーディングしました。

検討:

  • JPAは、テーブルではなくJavaオブジェクトエンティティで機能するように定義されています
  • エンティティ階層のルートであるAnimalは抽象化されていないため、インスタンスを作成して永続化できます。
  • Animal @DescriminatorColumnと@DescriminatorTypeのデフォルト値があります。したがって、Animalテーブルには、「DTYPE」という名前で「someStringtype」と入力された識別子列が追加されます。@DescriminatorValueのデフォルト値があります-エンティティ名:Animalと等しくなります。したがって、このエンティティを作成するときは、Animal.DTYPE column="Animal"です。
  • エンティティドッグにはスーパークラスの動物がいます。デフォルト値は、@DescriminatorValue-Dogにも使用されます。したがって、このエンティティを作成すると、Animal.DTYPE column="Dog"になります。
  • Javaクラスの制限により、Dogオブジェクトが存在する場合は常に、対応するAnimalスーパークラスオブジェクトも存在するようになります。
  • @DescriminatorValue(DTYPE列に格納された値)= "Dog"を使用してエンティティアニマルをJPA永続コンテキストにロードする場合、一貫性を保つためにDogオブジェクトをPCにロードすると非常に便利です。JPA標準では必須ではありませんが。
  • 継承関係をEAGERまたはLAZYに指定することはできません(基本タイプフィールドまたはエンティティ関係フィールドのように)。dogプロパティを読み取り/更新する必要があり、Dogクラスがロードされていない場合は、どうしますか?別のクエリを実行してリロードしますか?これにより、一貫性とパフォーマンスが大幅に低下します。
  • パフォーマンスの主な懸念事項は、DBに送信される個別のSQLコマンドの総数です。
    所要時間の観点から:動物テーブルを使用したクエリは、動物の外側を犬に結合したクエリよりもわずかに高速です(数十マイクロ秒???)が、2つの別々のクエリ(1つは動物用、もう1つは犬用)よりもはるかに高速です。
于 2012-11-02T07:09:41.870 に答える
0

実際には、スーパークラスだけを取得する方法があります。JPAからのネイティブクエリを使用する必要があります。私の場合、JPAリポジトリを使用しています。したがって、次のようになります。

@Query(value = "SELECT * FROM animal", nativeQuery = true)
List<Resource> findAllAnimal();

フラグnativeQueryをtrueにすると、データベースでネイティブSQLを実行できます。

Entity Managerを使用している場合は、これを確認してください:https ://www.thoughts-on-java.org/jpa-native-queries/

于 2018-05-09T20:33:13.767 に答える