JPA継承関係のマッピング


継承関係のマッピング


継承関係マッピングには、オブジェクトの継承関係をDBにマッピングする方法が含まれます.
リレーショナル・データベースは、オブジェクト向けの言語で継承されていない概念です.
逆に、スーパータイプのサブタイプ関係のモデリング方法は、オブジェクトの継承概念と最も似ています.
ORMでいう継承関係マッピングは,オブジェクトの継承構造とデータベースのスーパータイプサブタイプ関係のマッピングである.
オブジェクト継承モデル

スーパータイプサブタイプ論理モデルを実際の物理モデルのテーブルとして実装する場合、3つの方法が選択できます.
  • 各テーブルに変換:上図に示すように、各テーブルをテーブルとして作成し、クエリーするときに結合を使用します.JPAでは、これは結合ポリシーです.
  • 集計表に変換:1つの表のみを使用して集計します.JPAは、単一テーブルポリシーと呼ばれています.
  • サブタイプテーブルに変換:サブタイプごとにテーブルを作成します.JPAでは、各実装クラスをテーブルポリシーと呼ぶ.
  • 結合ポリシーは、上の図に示すように、各エンティティをテーブルとして作成し、サブテーブルが親テーブルのプライマリ・キーを受け入れ、プライマリ・キー+外部キーとして使用するポリシーです.したがって、クエリーでは結合がよく使用されます.
    このポリシーを使用する場合、オブジェクトはタイプで区別できますが、テーブルにはタイプ概念がありません.したがって、タイプを区別するカラムを追加する必要があります.ここでは、DTYPE列を区切り列として使用します.

    戦略に署名



    結合ポリシーサンプルコード
    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @DiscriminatorColumn(name = "DTYPE")
    public abstract class Item {
        @Id
        @GeneratedValue
        @Column(name = "item_id")
        private Long id;
    
        private String name;
        private int price;
    
    }
    
    @Entity
    @DiscriminatorValue("B")
    public class Book extends Item {
        private String author;
        private String isbn;
    }
    
    @Entity
    @DiscriminatorValue("A")
    public class Album extends Item {
        private String artist;
    
    }
    
    @Entity
    @DiscriminatorValue("M")
    public class Movie extends Item {
        private String director;
        private String actor;
    }
  • @Ingeritance(strategy = IngeritanceType.JOINED):継承マッピングは親クラスで@Ingeretanceを使用します.結合ポリシーIngeritanceType.JOINEDを使用したマッピングポリシーを指定する必要があります.
  • @DiscriminatorColumn(name = "DTYPE"):親に区切りバーを指定します.この列を使用して、格納されているサブテーブルを区別します.デフォルト値はDTYPEなので、@DiscriminatorColumnに縮小できます.
  • @DiscriminatorValue("M"):エンティティの保存時に区切りバーに入力する値を指定します.ムービーエンティティを指定すると、値MはDTYPEに区切り欄として格納されます.
  • デフォルトでは、サブテーブルは親テーブルのID列名を使用します.サブテーブルのデフォルトキー列名を変更する場合は、次のコードを使用します.
    @Entity
    @DiscriminatorValue("B")
    @PrimaryKeyJoinColumn(name = "BOOK_ID") //ID 재정의
    public class Book extends Item{
        private String author; //저자
        private String isbn;   // ISBN
    
    }
    長所
  • テーブルは正規化されています.
  • 外部キーは整合性制約を参照します.
  • ストレージの有効活用
  • 短所
  • クエリーでは結合が頻繁に使用され、パフォーマンスが低下する可能性があります.
  • クエリは非常に複雑です.
  • 登録データのINSERT SQLを2回実行します.
  • JPA規格では、区切りバーの使用が要求されていますが、一部のインプリメンテーション(Hypernetを含む)では、区切りバーは使用されません.

    単一テーブルポリシー


    単一のテーブル・ポリシーでは、次の図に示すように、名前付きのテーブルが1つしか使用されません.次に、どのサブデータが格納されているかを区切りバーで区切ります.クエリーでは結合は使用されないため、最も高速です.

    このポリシーを使用する場合、サブエンティティマッピングのすべてのカラムにnullを許可する必要があることに注意してください.たとえば、Bookエンティティを保存する場合はnullを入力します.これは、ITEMテーブルのAUTOR、ISBN列のみを使用し、他のエンティティにマッピングされたARTist、DIRECTOR、ACTOR列を使用しないためです.
    単一テーブル・ポリシーのサンプル・コード
    @Entity
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name = "DTYPE")
    public abstract class Item {
        @Id
        @GeneratedValue    
        @Column(name = "item_id")
        private Long id;
    
        private String name;
        private int price;
    }
    
    @Entity
    @DiscriminatorValue("B")
    public class Book extends Item {
        private String author;
        private String isbn;
    }
    
    @Entity
    @DiscriminatorValue("A")
    public class Album extends Item {
        private String artist;
    }
    
    @Entity
    @DiscriminatorValue("M")
    public class Movie extends Item {
        private String director;
        private String actor;
    }
    InheritanceType.SINGLE_TABLEを指定すると、単一のテーブルポリシーが使用されます.
    すべてのコンテンツを1つのテーブルに統合するため、区切りバーを必須項目として使用する必要があります.単一テーブルポリシーの長所と短所は、単一テーブルを使用する特徴に関係します.
    長所
  • 結合は必要ないので、クエリの速度は通常速いです.
  • クエリは簡単です.
  • 短所
  • サブエンティティマッピングのすべてのカラムにnullを許可する必要があります.
  • すべてのコンテンツを単一のテーブルに保存すると、テーブルが大きくなる可能性があります.したがって、場合によってはクエリのパフォーマンスが逆に遅くなることがあります.
  • 単一テーブルポリシーでは、区切りバー@DiscriminatorColumn@を設定する必要があります.DistributorValueが指定されていない場合、デフォルトではエンティティ名が使用されます.

    実装クラスごとのテーブルポリシー


    各インプリメンテーション・クラスのテーブル・ポリシーは、下図に示すように、サブエンティティごとにテーブルを作成します.各サブテーブルには、必要なすべてのカラムが含まれています.

    各インプリメンテーション・クラスのテーブル・ポリシーのサンプル・コード
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Item {
        @Id
        @GeneratedValue    
        @Column(name = "item_id")
        private Long id;
    
        private String name;
        private int price;
    }
    
    @Entity
    public class Book extends Item {
        private String author;
        private String isbn;
    }
    
    @Entity
    public class Album extends Item {
        private String artist;
    }
    
    @Entity
    public class Movie extends Item {
        private String director;
        private String actor;
    }
    InheritanceType.TABLE_PER_CLASSを選択した場合は、実装クラスごとにテーブルポリシーを使用します.このポリシーは、サブエンティティごとにテーブルを作成します.通常、このポリシーは推奨されません.
    長所
  • 領域分子タイプでは非常に有効である.
  • not null制約は使用できません.
  • 短所
  • 複数のサブテーブルを同時にブラウズする場合、パフォーマンスは低下します.
  • サブテーブルクエリのマージが困難です.
  • このポリシーでは、DBデザイナやORMエキスパートは推奨されません.サインや実況中継の戦略を考えてみましょう.

    @MappedSuperclass


    以前の転送では、継承関係マッピングは、親クラスと子クラスをデータベース・テーブルにマッピングしました.親がテーブルにマッピングされずに親を継承する子にのみマッピング情報を提供する場合は、@MappedSuperclassを使用します.
    抽象クラスと同様に、@Entityは実際のテーブルにマッピングされ、@MappedSuperClassは実際のテーブルにマッピングされません.これは、マッピング情報を継承するためにのみ使用されます.
    @MappedSuperclass
    public abstract class BaseEntity {
        @Id @GeneratedValue
        private Long id;
        private String name;
    }
    
    @Entity
    @Setter
    @Getter
    public class Member extends BaseEntity{
        // ID 상속
        // NAME 상속
        private String email;    
        ...
    }
    
    public class Seller extends BaseEntity{
        // ID 상속
        // NAME 상속
        private String shopName;
    }
    BaseEntityは、オブジェクトが主に使用する共通マッピング情報を定義します.子エンティティは、継承継承によってBaseEntityのマッピング情報を継承します.ここで、BaseEntityはテーブルにマッピングする必要はなく、サブエンティティに共通のマッピング情報を提供するだけです.そこで,@MappedSuperclassを用いた.
    @Entity
    @AttributeOverride(name = "id", column = @Column(name = "MEMBER_ID"))
    public class Member extends BaseEntity{
    
    }
    上のコードは、親からのid属性を継承するカラム名をMEMBER IDとして再定義します.
    マッピング情報を再定義するには、@AttributeOverridesまたは@AttributeOverrideを使用します.関連付けを再定義するには、@AssociationOverridesまたは@AssociationOverrideを使用します.

    @MappedSuperclassプロパティ

  • テーブルにマッピングされていない場合に、シンボルからサブクラスへのマッピング情報を継承するために使用される.
  • @MappedSuperclassで指定されたクラスはエンティティではないため、em.find()またはJPQLは使用できません.
  • 手動で作成する必要がほとんどないため、クラスを抽象クラスとして作成することをお勧めします.
  • 次に、テーブルに関係なく、エンティティでよく使用されるマッピング情報を収集するだけであることを宣言します.ORMが言う真の継承マッピングは、オブジェクト継承をデータベーススーパータイプサブタイプ関係にマッピングすることである.
    @MappedSuperclassを使用すると、登録日、変更日、登録者、変更者など、複数のエンティティでよく使用される属性を効率的に管理できます.
    出典:https://velog.io/@sa 1341/JPA-継承-関係-マッピング
    Java ORM標準JPAプログラミング(金英漢著)