JPAエンティティ継承のマッピング

4004 ワード

注:文章の中の実体は@Entityに注釈されたクラスを指すそうです.
JPAのオブジェクト関係マッピングは、通常、1つのエンティティが1つのテーブルに対応し、2つのエンティティの間には何の関係もありません.2つのエンティティ間が継承関係である場合、どのようにマッピングしますか?
JPAのエンティティは、継承マッピング、マルチステート関連付け、マルチステートクエリをサポートします.抽象クラスと特定のクラスはエンティティであり、@Entityを使用して注釈し、エンティティにマッピングし、クエリーをエンティティにカプセル化できます.エンティティークラスは非エンティティークラス、非エンティティークラス、またはエンティティークラスを継承できます.
JPAの継承マッピングには、次のような状況があります.
一、実体クラスは抽象(具体)実体クラスを継承する
抽象クラスはエンティティとして指定できます.抽象エンティティと特定のエンティティの唯一の違いは、抽象エンティティが直接インスタンス化できないことです.抽象エンティティは、エンティティにマッピングされ、クエリーのターゲットとして使用できます.
抽象エンティティクラスは@Entity注記またはXML記述子を使用してエンティティとして表されます.
このマッピングは比較的複雑で、後で例を挙げて説明する文章を書く.ここではもう言わないでください.
二、実体クラス継承マッピングスーパークラス(Mapped Superclasses)
エンティティは、永続化されたエンティティステータス(プロパティまたはフィールド)とマッピング情報を提供するスーパークラスから継承できますが、それ自体はエンティティではありません.通常、このスーパークラスマッピングの目的は、複数のエンティティが共有する状態とマッピング情報を定義することである.
マッピングスーパークラスはエンティティと異なり、クエリーできないため、EntityManagerまたはQueryインタフェースにパラメータとして渡すことはできません.マッピングスーパークラス定義の永続化関係は、一方向でなければなりません.
抽象クラスまたは特定のクラスは、@MappedSuperclass注記(またはmapped-superclass XML記述子要素)を使用してマッピングスーパークラスを指定するマッピングスーパークラスとして使用できます.
マッピングスーパークラスは、エンティティクラスから継承されるマッピング情報として作用する個別のテーブルを生成しません.
マッピングスーパークラスは、エンティティクラスのようにマッピングできますが、マッピングは、それ自体に個別のテーブルが存在しないため、継承されたエンティティクラスに作用します.サブクラスに作用すると、継承されたマッピング情報がサブクラスに対応するテーブルに作用します.サブクラスは、@AttributeOverrideおよびAssociationOverride注記または対応するXML記述子要素によって、マッピングスーパークラスのマッピング情報を上書きすることができる.次に例を示します.
package com.mikan;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public class Employee implements Serializable {

	private static final long serialVersionUID = -7674269980281525370L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer empId;
	
	@Column
	protected String name;

	// getter/setter  
	
}

package com.mikan;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "FT_EMP")
public class FullTimeEmployee extends Employee {

	private static final long serialVersionUID = 9115429216382631425L;

	//        empId name  

	@Column
	private Double salary;

	// getter/setter  
	
}

package com.mikan;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "PT_EMP")
public class PartTimeEmployee extends Employee {

	private static final long serialVersionUID = -6122347374515830424L;

	//        empId name  

	@Column(name = "hourly_wage")
	private Float hourlyWage;

	// getter/setter  
	
}
ここで、Employeeはマッピングスーパークラスであり、2つのフィールド(すなわち、上述した状態)と対応するマッピング情報を含むが、これらのマッピング情報はすべてサブクラスエンティティFullTimeEmployeeとPartTimeEmployeeによって継承され、それ自体は対応するテーブルを生成しない.FT_しか生成しませんEMPとPT_EMPの2つのテーブルで、この2つのテーブルのフィールドには、サブクラス自体のフィールドとマッピングスーパークラスから継承されたフィールドが含まれています.すなわちFT_EMPテーブルのフィールドは、empId、name、salary、PT_EMPテーブルのフィールドは、empId、name、hourly_です.wage.
三、実体クラスが非実体クラスを継承する
エンティティクラスは、特定のクラスであっても抽象クラスであってもよい非エンティティスーパークラスを継承することができます.
この非エンティティスーパークラスは継承動作としてのみ使用され、その状態は永続化されません.非エンティティスーパークラスから継承されたすべてのステータス(すなわち、プロパティまたはフィールド)は、エンティティサブクラスで永続化されず、エンティティマネージャはこれらのステータスを管理しません.非エンティティスーパークラスのすべての注記は無視されます.非エンティティスーパークラスは、EntityManagerまたはQueryインタフェースにパラメータとして渡すことはできません.
次に例を示します.
public class Cart {
	protected Integer operationCount; // transient state

	public Cart() {
		operationCount = 0;
	}

	public Integer getOperationCount() {
		return operationCount;
	}

	public void incrementOperationCount() {
		operationCount++;
	}
}

@Entity
public class ShoppingCart extends Cart {
	Collection items = new Vector();

	public ShoppingCart() {
		super();
	}

	@OneToMany
	public Collection getItems() {
		return items;
	}

	public void addItem(Item item) {
		items.add(item);
		incrementOperationCount();
	}
}

ShoppingCartに対応するテーブルにはoperationCountフィールドは含まれません.