Oracle® Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス 12c (12.2.1.2.0) E82670-01 |
|
前 |
次 |
この章では、EclipseLinkのJava Persistence API (JPA)注釈の拡張機能について説明します。EclipseLinkでは、Java Persistence API (JPA) 2.0仕様がサポートされています。多くの拡張機能も含まれています。
この章の内容は次のとおりです。
次に、機能ごとにカテゴリ化されたEclipseLinkの注釈の拡張機能を示します。
EclipseLinkには、次のマッピングに関する注釈の拡張機能が含まれています。
EclipseLinkには、次のエンティティに関する注釈の拡張機能が含まれています。
EclipseLinkには、次のデータ変換に関する注釈の拡張機能が含まれています。
EclipseLinkには、次のキャッシングに関する注釈の拡張機能が含まれています。
EclipseLinkには、次のコピー・ポリシーに関する注釈の拡張機能が含まれています。
EclipseLinkには、次のストアド・プロシージャおよびストアド・ファンクションに関する注釈の拡張機能が含まれています。
EclipseLinkには、次のパーティションの使用に関する注釈の拡張機能が含まれています。
EclipseLinkには、次の非リレーショナル・データ・ソースに関する注釈の拡張機能が含まれています。
次に、EclipseLinkの注釈の拡張機能を示します。
@AdditionalCriteria
を使用して、データに対するパラメータ化された表示を定義します。
エンティティまたはマップされたスーパークラスに対して、追加基準を定義できます。追加基準の定義は、マップされたスーパークラス・レベルで指定すると、エンティティによって独自の追加基準が定義されている場合(この場合、マップされたスーパークラスに定義された基準は無視されます)を除き、すべての継承エンティティに適用されます。
使用方法
追加基準により、問合せに追加のフィルタリング・メカニズムを提供できます。このフィルタリング・オプションには、たとえば、エンティティまたはマップされたスーパークラスに定義された、既存の追加のJOIN
式を使用したり、パラメータを渡すことができます。
追加基準のパラメータは、エンティティ・マネージャ・ファクトリまたはエンティティ・マネージャのプロパティを介して設定します。エンティティ・マネージャで設定されたプロパティは、エンティティ・マネージャ・ファクトリで設定された同じ名前のプロパティ・セットをオーバーライドします。問合せを実行する前に、エンティティ・マネージャでプロパティを設定する必要があります。エンティティ・マネージャの存続期間のプロパティは変更しないでください。
注意: 追加基準は、ネイティブSQL問合せではサポートされていません。 |
例
@AdditionalCriteria
注釈または<additional-criteria>
要素を使用して、追加基準を指定します。追加基準の定義では、すべての有効なJPQL文字列がサポートされており、追加基準を形成するために、別名としてthis
を使用する必要があります。次に例を示します。
@AdditionalCriteria("this.address.city IS NOT NULL")
例2-1に、エンティティEmployee
に対して定義された追加基準を示し、次に、エンティティ・マネージャに対して設定された追加基準のパラメータを示します。
例2-1 @AdditionalCriteria注釈の使用
次のように、Employee
に対して追加基準を定義します。
package model;
@AdditionalCriteria("this.company=:COMPANY")
public class Employee {
...
}
EntityManager
に対してプロパティを設定します。この例では、MyCompany
のすべての従業員が戻されます。
entityManager.setProperty("COMPANY", "MyCompany");
例2-2では、前と同じ例を示しますが、eclipselink-orm.xml
マッピング・ファイルの<additional-criteria>
要素を使用します。
例2-2 <additional-criteria> XMLの使用
<additional-criteria> <criteria>this.address.city IS NOT NULL</criteria> </additional-criteria>
追加基準の用途
追加基準には、次のような用途があります。
マルチテナンシ
マルチテナンシ環境では、テナント(ユーザー、クライアント、組織、アプリケーション)はデータベース表を共有できますが、データの表示は、テナントがそれ自身のデータにのみアクセスできるように制限されます。追加基準を使用して、そのような制限を構成できます。
例2-3 マルチテナンシの例1
次の例では、請求アプリケーションまたは請求組織などのBillingクライアントのデータを制限します。
@AdditionalCriteria("this.tenant = 'Billing'")
例2-4 マルチテナンシの例2
次の例は、同時に複数のテナントによって使用されるアプリケーションで使用できます。追加基準は、次のように定義されます。
@AdditionalCriteria("this.tenant = :tenant")
テナントがEntityManagerFactory
またはEntityManager
を取得すると、永続性/エンティティ・マネージャ・プロパティのテナントが、それを取得しているテナントの名前に設定されます。次に例を示します。
Map properties = new HashMap(); properties.put("tenant", "ACME"); EntityManagerFactory emf = Persistence.createEntityManagerFactory(properties);
または
Map properties = new HashMap(); properties.put("tenant", "ACME"); EntityManager em = factory.createEntityManager(properties);
ソフト削除
次の例では、削除するようにマークされている(ものの、表に存在する)データを問合せからフィルタリングします。
@AdditionalCriteria("this.isDeleted = false")
データ履歴
次の例では、問合せから最新データを戻すことによって、履歴表に格納されているデータなどの最新でないデータをフィルタリングします。
@AdditionalCriteria("this.endDate is null")
注意: EclipseLinkは、HistoryPolicy 経由で特定の履歴サポートも提供しています。詳細は、EclipseLinkの理解の履歴ポリシーに関する項を参照してください。 |
@Array
を使用して、OracleのVARRAY
型やPostgreSQL JDBCのArray
型など、特定のデータベースによってサポートされるオブジェクト・リレーショナル・データ・タイプを定義します。
表2-2 @Arrayの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)データベースの配列の構造型の名前 |
|
|
(Javaの汎用型を使用してコレクション・フィールドまたはプロパティが定義される場合のみオプション、それ以外の場合は必須)コレクションの要素タイプであるクラス(基本または埋込み可能) |
コレクションのパラメータ化型 |
例
例2-5に、Oracle VARRAY
型とともにこの注釈を使用する方法を示します。
例2-5 @ArrayとOracle VARRAYの使用
VARRAY DDL: CREATE TYPE TASKS_TYPE AS VARRAY(10) OF VARCHAR(100)
@Struct @Entity public class Employee { @Id private long id; @Array(databaseType="TASKS_TYPE") private List<String> tasks; }
例2-6に、PostgreSQL Struct
型とともにこの注釈を使用する方法を示します。
@BatchFetch
を使用して、単一の問合せで読み取られる関連マッピング(@OneToOne
、@OneToMany
、@ManyToMany
、@ElementCollection
など)に関連するオブジェクトを読み取ります。
表2-3 @BatchFetchの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
size |
バッチ・フェッチのデフォルトのサイズ。 |
|
BatchFetchType |
(オプション)使用するバッチ・フェッチのタイプは、次のとおりです。
|
|
使用方法
バッチ・フェッチにより、ツリーの最適なロードが可能になります。@BatchFetch
注釈をツリー構造の子関係で設定すると、EclipseLinkは、各レベルに対して1つのSQL文を使用します。たとえば、PHONE
にEMPLOYEE
に対する外部キーがあるEMPLOYEE
表およびPHONE
表を使用してオブジェクトについて考えます。デフォルトでは、従業員のアドレス・リストを読み取るには、従業員のアドレスごとの、n回の問合せが必要になります。バッチ・フェッチでは、すべてのアドレスに対して1つの問合せを使用します。
BatchFetchType=EXISTS
の使用にはSQL DISTINCT
文(LOBに関する問題が発生する可能性があります)が必要ないため、一部のタイプの問合せや、特定のデータベースでは、より効率的である場合があります。
BatchFetchType=IN
を使用すると、EclipseLinkでは、まだキャッシュにないオブジェクトのみを選択します。この方法は、カーソルやページ区切りに対して、またはJOIN
を使用できない状況において、より役立つ場合があります。一部のデータベースでは、シングルトンIDに対してのみ機能します。
例
次の例では、様々なバッチ・フェッチ・タイプとともにこの注釈(およびXML)を使用する方法を示します。
例2-7 JOIN BatchFetchタイプの使用
@OneToOne @BatchFetch(BatchFetchType.JOIN) private Address address;
<one-to-one name="address"> <batch-fetch type="JOIN" /> </one-to-one>
@Cache
を(JPA @Cachable
注釈のかわりに)使用して、EclipseLinkオブジェクト・キャッシュを構成します。デフォルトでは、EclipseLinkは、共有オブジェクト・キャッシュを使用してすべてのオブジェクトをキャッシュします。最適なキャッシングを可能にするために、クラスごとにキャッシュのタイプとオプションを構成できます。
表2-4 @Cacheの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)この属性を、次の項目を使用するキャッシュのタイプ(
次の永続性ユニット・プロパティで、この属性をオーバーライドできます。
|
|
|
(オプション) int値にこの属性を設定して、使用するキャッシュ・サイズ(オブジェクト数)を定義します。 |
|
|
(オプション)エンティティのキャッシュ・レベル。
|
|
|
(オプション) |
失効なし |
|
(オプション)キャッシュされるインスタンスの有効期限が切れる特定の時刻( |
失効なし |
|
(オプション) trueのブール値に設定すると、データベースにアクセスするすべての問合せによって、常にキャッシュがリフレッシュされます。 |
|
|
(オプション) 注意:
|
|
|
(オプション) trueのブール値に設定すると、すべての問合せに対して、キャッシュでのヒットを取得しない一方で、アイデンティティはキャッシュに対して解決することが強制されます。これにより、すべての問合せによってデータベースのヒットが取得されます。 |
|
|
(オプション)この属性をキャッシュ・コーディネーション・モード(
永続性ユニット・プロパティでもキャッシュ・コーディネーションを構成する必要があります。「キャッシング」を参照してください。 |
|
|
(オプション)データベース変更通知モード。
|
|
使用方法
JPA @Cachable
注釈のかわりに@Cache
注釈を使用して、キャッシュ構成を追加します。
@Cache
注釈は、次のものに定義できます。
@Entity
@MappedSuperclass
継承階層のルート(該当する場合)
継承サブクラスで@Cache
注釈を定義すると、注釈は無視されます。@Embeddable
で@Cache
注釈を定義すると、EclipseLinkは例外をスローします。
EclipseLinkでのキャッシング
EclipseLinkキャッシュは、クラスと主キーの値に基づいて最近読み取られたり書き込まれたオブジェクトが格納される、インメモリー・リポジトリです。EclipseLinkでは、次の目的でこのキャッシュが使用されます。
最近読み取られたり書き込まれたオブジェクトを保持し、メモリー内でそれらにアクセスしてデータベースへのアクセスを最小限にすることで、パフォーマンスを向上させます。
ロックと分離レベルを管理します。
オブジェクト・アイデンティティを管理します。
EclipseLinkキャッシュとそのデフォルトの動作の詳細は、次を参照してください。
EclipseLinkの理解のキャッシングの理解に関する項
EclipseLinkソリューション・ガイドのオブジェクト・キャッシングに関する項
EclipseLinkには、次のエンティティ・キャッシング注釈が定義されています。
@Cache
EclipseLinkにより、キャッシュを構成するために指定できる多数の永続性ユニット・プロパティも提供されます。これらのプロパティを注釈のかわりに使用したり、注釈を補完できる場合があります。
詳細は、「キャッシング」を参照してください。
例
例2-10では、@Cache
注釈を示します。
例2-10 @Cache注釈の使用
... @Entity @Cache( type=CacheType.SOFT, // Cache everything until the JVM decides memory is low. size=64000 // Use 64,000 as the initial cache size. expiry=36000000, // 10 minutes coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS // if cache coordination is used, only send invalidation messages. ) public class Employee { ... }
例2-11に、eclipselink-orm.xml
ファイルのこの注釈を使用する方法を示します。
例2-11 <cache> XMLの使用
<entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd" version="2.4"> <entity name="Employee" class="org.acme.Employee" access="FIELD"> <cache type="SOFT" size="64000" expiry="36000000" coordination-type="INVALIDATE_CHANGED_OBJECTS"/> </entity> </entity-mappings>
また、ここに示すように、永続性ユニット・レベル(persistence.xml
ファイル)でキャッシング・プロパティを指定することもできます。
例2-12 persistence.xmlでのキャッシングの指定
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd" version="2.0"> <persistence-unit name="acme" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.cache.shared.default" value="false"/> <property name="eclipselink.cache.shared.Employee" value="true"/> <property name="eclipselink.cache.type.Employee" value="SOFT"/> <property name="eclipselink.cache.size.Employee" value="64000"/> </properties> </persistence-unit> </persistence>
@CacheIndex
を使用して、キャッシュされる索引を定義します。キャッシュ索引は、キャッシングが有効なときにのみ使用されます。
表2-5 @CacheIndexの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)索引を定義する一連の列。フィールド/メソッドに注釈が付けられている場合は不要です。 |
|
|
(オプション)索引付きのフィールドが更新可能かどうかを指定します。
|
true |
使用方法
キャッシュ索引により、索引付きのフィールドで問合せするときに、singleResult
問合せでキャッシュ・ヒットを取得できます。すべてのオブジェクトがメモリー内にあるかどうかは不明なため(キャッシュ使用率の問合せヒントが使用されない場合)、resultList
問合せではキャッシュ・ヒットを取得できません。
索引は、一意である必要があります。一意でない場合、最初の索引付きオブジェクトが戻されます。
エンティティ・クラスまたは属性で@CacheIndex
を使用できます。属性で定義される場合、列がデフォルトに設定されます。
例
例2-13に、@CacheIndex
注釈の使用例を示します。
例2-13 @CacheIndex注釈の使用
@Entity
@CacheIndex(columnNames={"F_NAME", "L_NAME"}, updateable=true)
public class Employee {
@Id
private long id;
@CacheIndex
private String ssn;
@Column(name="F_NAME")
private String firstName;
@Column(name="L_NAME")
private String lastName;
}
例2-14に、eclipselink-orm.xml
ファイルの<cache-index>
XML要素の使用例を示します。
例2-14 <cache-index> XMLの使用
<?xml version="1.0"?> <entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd" version="2.4"> <entity name="Employee" class="org.acme.Employee" access="FIELD"> <cache-index updateable="true"> <column-name>F_NAME</column-name> <column-name>L_NAME</column-name> </cache-index> <attributes> <id name="id"/> <basic name="ssn"> <cache-index/> </basic> <basic name="firstName"> <column name="F_NAME"/> </basic> <basic name="lastName"> <column name="L_NAME"/> </basic> </attributes> </entity> </entity-mappings>
例2-15に、キャッシュ索引を使用する問合せの例を示します。
エンティティで@CacheInterceptor
を使用して、イベントを通じてキャッシュ操作に応答するかわりに、エンティティに対するすべてのEclipseLinkのキャッシュ・アクセスをインターセプトします。
使用方法
一度設定すると、指定されたクラスがすべてのキャッシュ・コールを受信します。既存のEclipseLinkのキャッシュ設定は引き続き使用され、EclipseLinkキャッシュに対して継続できるすべてのコールは構成されたキャッシュに対して実行されます。
継承でエンティティとともに使用する場合、継承階層のルートに@CacheInterceptor
を定義する必要があります。
例
例2-16に、外部キャッシュをEclipseLinkと統合する方法を示します。
例2-16 Using @CacheInterceptor注釈の使用
この例では、Employee
クラスが、EclipseLinkの内部キャッシュに対するすべてのEclipseLinkコールをインターセプトし、Oracle Coherence Gridのキャッシュ(CoherenceInterceptor
)にリダイレクトします。
import oracle.eclipselink.coherence.integrated.cache.CoherenceInterceptor;
import org.eclipse.persistence.annotations.Customizer;
@Entity
@CacheInterceptor(value = CoherenceInterceptor.class)
public class Employee {
...
}
例2-17に、eclipselink-orm.xml
ファイルの<cache-interceptor>
XML要素の使用例を示します。
@CascadeOnDelete
注釈を使用して、データベース・オブジェクトで実行される削除操作をセカンダリ表または関連表にカスケードするように指定します。
ON DELETE CASCADE
は、データベースの外部キーの制約オプションで、依存行を自動的に削除します。
使用方法
ターゲットがソース・エンティティに対する外部キーとして定義されているすべてのリレーションシップに@CascadeOnDelete
を置くことができます。
次のソース・リレーションシップに注釈を追加します。@OneToOne
、@OneToMany
、@ManyToMany
および@ElementCollection
。また、@SecondaryTable
またはJOINED
継承のあるエンティティに@CascadeOnDelete
を追加することもできます。表2-8では、次の異なる要素に@CascadeOnDelete
を置くことによって、どのような影響があるかについて説明します。
表2-8 異なる要素での@Cascadeの使用
要素 | @CascadeOnDeleteの影響 |
---|---|
エンティティ |
セカンダリ表または結合された継承表がデータベースに削除をカスケードすることを定義します。 |
OneToOneマッピング |
関連オブジェクトの削除は、データベースにカスケードされます。 このことは、mappedBy/ターゲット外部キーのOneToOneマッピングにのみ許可されます(制約方向のため)。 |
OneToManyマッピング |
|
ManyToManyマッピング |
結合表の削除がデータベースにカスケードされます(制約方向により、プライベートでもターゲット・オブジェクトはカスケードできません)。 |
ElementCollectionマッピング |
コレクション表の削除が、データベースにカスケードされます。 |
@CascadeOnDelete
には、次の動作があります。
DDL生成: DDL生成を使用して生成された制約には、カスケード削除オプションが含められます。
エンティティ: セカンダリ表または結合された継承表からの削除では、SQLは実行されません(制約によって削除が処理されるため)。
OneToOne: マッピングでカスケードまたはorphanRemovalが使用される場合、ターゲット・オブジェクトを削除するためのSQLは実行されません。
OneToMany: マッピングでカスケードまたはorphanRemovalが使用される場合、ターゲット・オブジェクトを削除するためのSQLは実行されません。
ManyToMany: 結合表から削除するためのSQLは実行されません。
ElementCollection: コレクション表から削除するためのSQLは実行されません。
キャッシュ: カスケードされたオブジェクトが、キャッシュまたは永続性コンテキストから削除されます。
バージョン・ロック: カスケードされたオブジェクトの削除時に、バージョンは確認されません。
イベント: オブジェクトがロードされていない場合、カスケードされたオブジェクトで削除イベントが実行されないことがあります。
カスケード: CascadeOnDeleteを使用する場合、マッピングでカスケードするように削除操作を構成する必要があります。
例
例2-18に、従業員のセカンダリ表およびすべての所有されたリレーションシップのカスケード削除を示します。
例2-18 @CascadeOnDelete注釈の使用
@Entity
@SecondaryTable(name="EMP_SALARY")
@CascadeOnDelete
public class Employee{
@Id
private long id;
private String firstName;
private String lastName;
@Column(table="EMP_SALARY")
private String salary;
@OneToOne(mappedBy="owner", orphanRemoval=true, cascade={CascadeType.ALL})
@CascadeOnDelete
private Address address;
@OneToMany(mappedBy="owner", orphanRemoval=true, cascade={CascadeType.ALL})
@CascadeOnDelete
private List<Phone> phones;
@ManyToMany
@JoinTable(name="EMP_PROJ")
@CascadeOnDelete
private List<Project> projects;
...
}
eclipselink-orm.xml
ディスクリプタ・ファイルで、例2-19に示すとおり削除時のカスケードを指定します。
@ChangeTracking
を使用して、org.eclipse.persistence.descriptors.changetracking.ObjectChangePolicy
を指定します。このポリシーでは、EclipseLinkのコミット処理の変更セットを計算し、変更される属性が1つ以上ある変更セットの計算にオブジェクトを含めることによって、トランザクションを最適化します。
表2-9 @ChangeTrackingの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)使用する変更追跡ポリシーは、次のとおりです。
|
|
使用方法
自動ポリシーを使用すると問題があるアプリケーションの場合は、この注釈を使用して、別の変更ポリシーを構成します。@ChangeTracking
を使用すると、いくつかの属性を持つオブジェクトや多数の変更された属性を持つオブジェクトのコミット・パフォーマンスが向上することがあります。
注意: ATTRIBUTE またはOBJECT とともに変更追跡を使用する場合に、リフレクションを介してオブジェクトのフィールドを変更すると、EclipseLinkによって変更が検出されなくなります。ただし、DEFERRED を使用すると、EclipseLinkによって変更が検出されます。 |
例
例2-20に、@ChangeTracking
を使用して、作業ユニットの変更ポリシーを設定する方法を示します。
例2-21に、eclipselink-orm.xml
ファイルの<change-tracking>
要素を使用する方法を示します。
例2-21 <change-tracking> XMLの使用
<entity class="Employee"
<change-tracking type="DEFERRED"/>
...
</entity>
例2-22に、永続性ユニットのpersistence.xml
ファイルで、またはproperty
マップをインポートすることによって、変更追跡を構成する方法を示します。
@ClassExtractor
を使用して、識別子列を提供するかわりに、カスタム・クラス・インジケータを定義します。
使用方法
既存のデータベースにマップしており、表に識別子列がない場合、@ClassExtractor
注釈または<class-extractor>
要素を使用して継承を定義できます。クラス・エクストラクタは、ClassExtractor
インタフェースを実装するクラスを取得します。このクラスのインスタンスは、データベース行に使用するクラス・タイプの決定に使用されます。クラス・エクストラクタは、データベースRecord
およびSession
を取得するextractClassFromRow
メソッドを定義する必要があります。
クラス・エクストラクタがSINGLE_TABLE
継承とともに使用される場合、問合せでクラス・タイプの行をフィルタリングできる必要があります。これは、ブランチ・クラスのonlyInstancesExpression
またはwithAllSubclassesExpression
を設定することによって実現できます。これらは、DescriptorCustomizer
を使用してExpression
オブジェクトに設定できます。
例
例2-23に、ClassExtractor
を使用して継承を定義する例を示します。
例2-23 @ClassExtractor注釈の使用
@Entity
@Table(name="MILES_ACCOUNT")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@ClassExtractor(AirMilesClassExtractor.class)
@Customizer(AirMilesCustomizer.class)
public class AirMilesAccount implements Serializable {
@Id
private Long id;
@Basic
private String totalMiles;
@Basic
private String milesBalance;
...
}
@Entity
@Customizer(PreferredCustomizer.class)
public class PreferredAccount extends AirMilesAccount {
...
}
public class AirMilesClassExtractor implements ClassExtractor {
public void extractClassFromRow(Record row, Session session) {
if (row.get("TOTALMILES").lessThan(100000)) {
return AirMilesAccount.class;
} else {
return PreferredAccount.class;
}
}
}
public class AirMilesCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
ExpressionBuilder account = new ExpressionBuilder();
Expression expression = account.getField("TOTALMILES").lessThan(100000);
descriptor.getInheritancePolicy().setOnlyInstancesExpression(expression);
}
}
public class PreferredCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
ExpressionBuilder account = new ExpressionBuilder();
Expression expression = account.getField("TOTALMILES").greaterThanEqual(100000);
descriptor.getInheritancePolicy().setOnlyInstancesExpression(expression);
}
}
例2-24に、eclipselink-orm.xml
ファイルの<class-extractor>
要素を使用する方法を示します。
@CloneCopyPolicy
を使用して、エンティティにorg.eclipse.persistence.descriptors.copying.CloneCopyPolicy
を指定します。
表2-11 @CloneCopyPolicyの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション) methodは、EclipseLinkの |
|
|
(オプション) |
注意: method またはworkingCopyMenthod のいずれかを指定する必要があります。 |
使用方法
クローンmethod
では、オブジェクトのシャロー・クローンを実行します。これは、共有キャッシュ内のインスタンスから非永続フィールドをクローニングするために使用できます。
@CloneCopyPolicy
は、エンティティ、MappedSuperclassまたは埋込み可能クラスに指定できます。
@CompositeMember
を使用して、クラスがコンポジット永続性ユニットに属すことを示します。
ターゲット・タイプがプリミティブ型であり、かつ、ソース・コンポジット・メンバー永続性ユニット以外のコンポジット・メンバー永続性ユニットに属する表が@CollectionTable
によって指定される場合に使用します。これにより、ソースおよびターゲットを様々なデータベースにマップできます。
表2-12 @CompositeMemberの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
要素表が属するターゲット・コンポジット・メンバー永続性ユニットの名前(ソース・コンポジット・メンバー永続性ユニットと異なる場合) |
使用方法
@CompositeMember
注釈は、コンポジット・メンバー永続性ユニットにない場合は無視されます。@ElementCollection
注釈および@CollectionTable
注釈とともに使用される場合があります。
例
次の例に示すとおり、注釈またはeclipselink-orm.xml
ファイルを使用してCompositeMember
を構成できます。
@ConversionValue
を使用して、ObjectTypeConverter
のデータベース値およびオブジェクト値を指定します。
使用方法
JPA仕様により、データベース値がEnum
の名前または序数値のいずれかである場合、@Enumerated
注釈を使用してEnum
をデータベース列にマップできます。EclipseLinkでは、コンバータを使用してEnum
をコード化された値にマップすることもできます。
例
例2-29では、enum
Gender(MALE, FEMALE)
がデータベースの単一文字(M=MALEおよびF=FEMALE)にマップされます。
例2-29 @ConversionValue注釈の使用
@ObjectTypeConverter(name = "gender", objectType = Gender.class, dataType = String.class, conversionValues = { @ConversionValue(objectValue = "Male", dataValue = "M"), @ConversionValue(objectValue = "Female", dataValue = "F") }) ... @Basic @Convert("gender") private Gender gender = Gender.Male;
例2-30では、XMLを使用する同じ機能を示します。
例2-30 <conversion-value> XMLの使用
<object-type-converter name="gender" object-type="model.Gender "data-type="java.lang.String"> <conversion-value object-value="Male" data-value="M" /> <conversion-value object-value="Female" data-value="F" /> </object-type-converter> ... <basic name="gender"> <column name="GENDER" /> <convert>gender</convert> </basic>
@Convert
を使用して、名前付きコンバータを対応するマップ済属性とともに使用する必要があることを指定します。
使用方法
@Convert
には、次の予約名があります。
serialized: 関連付けられたマッピングにorg.eclipse.persistence.mappings.converters.SerializedObjectConverter
を配置します。
class-instance: 関連付けられたマッピングでClassInstanceConverter
を使用します。ClassInstanceConverter
を使用する場合、データベース表現はクラス名を表すString
になり、オブジェクト・モデル表現は引数なしのコンストラクタで構築されたクラスのインスタンスになります。
none: 関連付けられたマッピングにコンバータを配置しません。
@Converter
注釈を使用して、マップ済属性の読取りおよび書込み中にデータ値を変更するための、カスタム・コンバータを指定します。
表2-15 @Converterの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
コンバータの |
なし |
|
コンバータのクラス。このクラスは、 |
なし |
使用方法
@Converter
を使用して、マッピングとともに使用できる名前付きコンバータを定義します。コンバータは、エンティティ・クラス、メソッドまたはフィールドに定義できます。基本またはElementCollectionマッピングで@Convert注釈を使用してコンバータを指定します。
非JPAコンバータ注釈の使用
EclipseLinkは、(JPAのデフォルト・タイプ・マッピングに加えて)次の一連の非JPAコンバータ注釈を提供します。
永続性プロバイダは、次の順序でコンバータ注釈を検索します。
@Convert
@Enumerated
@Lob
@Temporal
シリアライズ(自動)
次のクラスでコンバータを指定します。
@Entity
@MappedSuperclass
@Embeddable
次のマッピングとともにコンバータを使用します。
@Basic
@Id
@Version
@ElementCollection
コンバータがその他のタイプのマッピング注釈によって指定されている場合、例外がスローされます。
例
例2-32に、@Converter
注釈を使用してgender
フィールドのコンバータ・クラスを指定する方法を示します。
例2-32 @Converter注釈の使用
@Entity
public class Employee implements Serializable{
...
@Basic
@Converter (
name="genderConverter",
converterClass=org.myorg.converters.GenderConverter.class
)
@Convert("genderConverter")
public String getGender() {
return gender;
}
...
}
例2-33に、eclipselink-orm.xml
ファイルの<converter>
要素を使用する方法を示します。
@CopyPolicy
を使用して、エンティティにorg.eclipse.persistence.descriptors.copying.CopyPolicy
を設定し、永続性要素のコピーを作成します。
表2-17 @CopyPolicyの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)コピー・ポリシーのクラス。クラスは、 |
@Customizer
を使用して、org.eclipse.persistence.config.DescriptorCustomizer
を実装し、すべてのメタデータ処理が完了した後にエンティティのクラス・ディスクリプタに対して実行するクラスを指定します。
使用方法
この注釈を使用して、EclipseLinkネイティブAPIによってマッピング・メタデータをカスタマイズまたは拡張します。@Customizer
を使用すると、その他のEclipseLink機能および構成にアクセスできます。
@Customizer
は、エンティティ、MappedSuperclassまたは埋込み可能クラスに指定できます。
注意: @Customizer は、親クラスから継承されません。 |
例
例2-36に、次のDescriptorCustomer
とともに@Customizer
注釈を使用する方法を示します。
public class MyCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
DirectToFieldMapping genderMapping = (DirectToFieldMapping)descriptor.getMappingForAttributeName("gender");
ObjectTypeConverter converter = new ObjectTypeConverter();
convert.addConversionValue("M", Gender.MALE);
convert.addConversionValue("F", Gender.FEMALE);
genderMapping.setConverter(converter);
}
}
例2-36 @Customizer注釈の使用
@Entity
@Table(name="EMPLOYEE")
@Customizer(mypackage.MyCustomizer.class)
public class Employee implements Serializable {
...
}
例2-37に、eclipselink-orm.xml
ファイルの<customizer>
要素を使用する方法を示します。
@DeleteAll
を使用して、リレーションシップを削除するときに、EclipseLinkがすべて削除問合せを使用する必要があることを示します。このことは、通常、リレーションシップがPrivateOwned
のであり、その所有者が削除されている場合に発生します。その場合、リレーションシップのメンバーは読み込まれることなく削除されます。
@ExcludeDefaultMappings
を使用して、特定のクラスにデフォルト・マッピングを追加しないことを指定します。かわりに、EclipseLinkは、注釈またはXMLマッピング・ファイルによって明示的に定義されているマッピングのみを使用します。
@ExistenceChecking
を使用して、エンティティが新しいか、または存在するかをEclipseLinkがどのような方法で確認するかを指定します。
merge()
操作では、@ExistenceChecking
を使用して、オブジェクトが存在するかどうか、つまり、オブジェクトを(データベースまたはキャッシュから)読み取る必要があるかどうかを決定するために、EclipseLinkがキャッシュのみを使用するかどうかを指定します。デフォルトでは、オブジェクトはデータベースから読み取られます。
表2-20 @ExistenceCheckingの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)次の存在チェック・タイプを設定します。
|
|
使用方法
@ExistenceChecking
は、エンティティまたはMappedSuperclassに指定できます。
EclipseLinkでは、次の存在チェック・タイプがサポートされています。
ASSUME_EXISTENCE
: オブジェクトの主キーにnull
が含まれていない場合、その主キーが存在する必要があります。アプリケーションが存在チェックを保証する場合または存在チェックを考慮しない場合に、このオプションを使用できます。
ASSUME_NON_EXISTENCE
: オブジェクトは存在しないと想定します。アプリケーションが存在チェックを保証する場合または存在チェックを考慮しない場合に、このオプションを使用できます。常にINSERT
操作が強制されます。
CHECK_CHACHE
: オブジェクトの主キーにnull
が含まれておらず、キャッシュに含まれている場合、その主キーが存在する必要があります。
CHECK_DATABASE
: データベースでSELECT
を実行します。
@FetchAttribute
を使用して、フェッチ・グループ内のパフォーマンスを向上させます。オブジェクトの属性のグループをオンデマンドでロードできるようにします。その結果、明示的なアクセス・コールが発生するまで、属性のデータをデータソースからロードする必要がなくなります。
これにより、ユーザーが一部の属性のみを必要とする場合に、オブジェクトの属性のすべてのデータをロードする必要がなくなります。
使用方法
EclipseLinkには、次の2つのタイプのフェッチ・グループがあります。
エンティティまたはMappedSuperclassレベルの事前定義済フェッチ・グループ
問合せレベルの動的(ユースケース)フェッチ・グループ
フェッチ・グループを使用する場合、広範囲にわたってユースケースを確認する必要があります。多くの事例では、追加のラウンドトリップにより、遅延したロードによって得られるメリットが相殺されます。
例
例2-42に、@FetchGroup
注釈内で@FetchAttribute
を使用する方法を示します。
例2-42 @FetchAttribute注釈の使用
@Entity @FetchGroup(name="basic-fetch-group", attributes={ @FetchAttribute(name="id"), @FetchAttribute(name="name"), @FetchAttribute(name="address")}) public class Person { @Id private int id; private String name; @OneToOne(fetch=LAZY) private Address address; @ManyToOne(fetch=EAGER) private ContactInfo contactInfo;
@FetchGroup
を使用して、必要に応じて属性のグループをオンデマンドでロードします。
これにより、ユーザーがオブジェクトの属性の一部のみを必要とする場合に、そのすべてのデータをロードする無駄を回避できます。属性に対して明示的なアクセス・コールが最初に発生するまで、基礎となるデータ・ソースから属性のデータをロードする必要がなくなることも意味します。
表2-22 @FetchGroupの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)フェッチする属性のリスト |
なし |
|
(必須)フェッチ・グループ名 |
なし |
|
(オプション)フェッチ・グループで指定されたすべてのリレーションシップ属性をロードする必要があるかどうかを示します。 |
|
使用方法
@FetchGroup
を使用する場合は、ユースケース分析を入念に実行する必要があります。遅延したロードによって得られるメリットは、追加のラウンドトリップによって相殺される場合があります。
EclipseLinkでは、次の2つのレベルのフェッチ・グループがサポートされています。
エンティティまたはMappedSuperclassレベルの事前定義済フェッチ・グループ
問合せレベルの動的(ユースケース)フェッチ・グループ
ウィービングを使用する場合、またはフェッチ・グループを定義する個々のクラスがorg.eclipse.persistence.queries.FetchGroupTracker
インタフェースを明示的に実装する場合にのみ、フェッチ・グループを使用できます。
フェッチ・グループを使用すると、オブジェクトの属性のサブセットを定義したり、フェッチ・グループを問合せに関連付けることができます。問合せを実行すると、EclipseLinkによりフェッチ・グループ内の属性のみが取得されます。除外された属性のいずれかに関するgetメソッドをコールすると、EclipseLinkでは、このサブセットから除外されたすべての属性をフェッチする問合せが自動的に実行されます。
1つのクラスに対して、複数のフェッチ・グループを定義できます。オプションで、その中で最大で1つのフェッチ・グループをデフォルト・フェッチ・グループとして指定できます。フェッチ・グループを指定しないで問合せを実行すると、EclipseLinkでは、その他に問合せが構成されていないかぎり、デフォルト・フェッチ・グループを使用します。
フェッチ・グループを使用する前に、システムの使用状況を綿密に分析しておくことをお薦めします。多くの事例では、フェッチ・グループに含まれない属性をロードするために必要な追加の問合せにより、部分的な属性のロードによって得られるメリットがかなり相殺されているためです。
例
例2-44に、この注釈を使用する方法を示します。
例2-44 Using @FetchGroup注釈の使用
@FetchGroup(name="names", attributes={
@FetchAttribute(name="firstName"),
@FetchAttribute(name="lastName")})
例2-45に、eclipselink-orm.xml
ファイルでこの機能を使用する方法を示します。
例2-45 <fetch-group> XMLの使用
<entity class="model.Employee"> <secondary-table name="SALARY" /> <fetch-group name="names"> <attribute name="firstName" /> <attribute name="lastName" /> </fetch-group> ...
例2-46に示すとおり、名前付きフェッチ・グループを問合せとともに使用することもできます。
@FetchGroups
を使用して、@FetchGroup
のグループを定義します。
使用方法
@FetchGroups
は、エンティティまたはMappedSuperclassに指定できます。
永続性ユニットのウィービングによって、フェッチ・グループを有効または無効にすることもできます。
例
フェッチ・グループの使用例は、「@FetchGroup」を参照してください。
例2-47に、永続性ユニットのpersistence.xml
ファイルで、またはproperty
マップをインポートすることによって、フェッチ・グループを構成する方法を示します。
@HashPartitioning
を使用して、オブジェクト(オブジェクトの場所またはテナントなど)からのフィールド値のハッシュによって、データベース・クラスタへのアクセスをパーティション化します。ハッシュによって、接続プールのリストに索引が付けられます。
表2-25 @HashPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)パーティション・ポリシーの名前。名前は、永続性ユニット内で一意である必要があります。 |
|
|
(必須)問合せをパーティション化するためのデータベース列または問合せパラメータ |
|
|
(オプション)パーティション化するための接続プール名のリスト |
ServerSessionのすべての定義済プール |
|
(オプション)パーティション・ハッシュを含まない問合せをすべてのデータベースに送信し、結果を統合するかどうかを指定します。 |
False |
使用方法
ハッシュ値を持つオブジェクトに対するすべての書込みまたは読取り要求は、サーバーに送信されます。パラメータとしてフィールドを含まない問合せは、次のように処理されます。
すべてのサーバーに送信され、統合されます。
または
セッションのデフォルトの動作に基づいて処理されます。
パーティション化は、エンティティ、リレーションシップ、問合せ、またはセッション/永続性ユニットで有効にできます。パーティション・ポリシーは、グローバルに名付けられ(再利用を可能にするため)、@Partitioned
注釈を使用して設定する必要があります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
索引は、表に対して定義されるデータベース構造であり、これにより一連の列に対する問合せと検索のパフォーマンスが向上します。eclipselink-orm.xml
ディスクリプタ内のコードまたは<index>
要素で@Index
注釈を使用して、表に索引を作成します。
エンティティまたは属性で索引を定義できます。エンティティの場合、索引に対して一連の列を定義する必要があります。
索引の作成はデータベース固有です。一部のデータベースは索引をサポートしていない可能性があります。ほとんどのデータベースでは、主キーと外部キーの列が自動的に索引付けされます。一部のデータベースでは、高度な索引DDLオプションがサポートされています。より高度な索引DDLを作成するために、DDLスクリプトまたはネイティブ問合せを使用できます。
表2-26 @Indexの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション) |
デフォルトのカタログ |
|
(フィールド/メソッドに注釈が付けられている場合は不要)索引を定義する一連の列を指定します。 |
エンティティの場合は、なし。 属性の場合は、その属性の列。 |
|
(オプション) |
|
|
(オプション) |
デフォルトのスキーマ |
|
(オプション)索引を定義する表。デフォルトはエンティティのプライマリ表です。 |
エンティティのプライマリ表。 |
|
(オプション)索引が一意か、または非一意であるかを指定します。 |
|
例
この例では、名に1つ、姓に1つ、および名と姓に複数列の索引、という3つの索引を定義します。
例2-48 @Index注釈の使用
@Entity @Index(name="EMP_NAME_INDEX", columns={"F_NAME","L_NAME"}) public class Employee{ @Id private long id; @Index @Column(name="F_NAME") private String firstName; @Index @Column(name="L_NAME") private String lastName; ... }
次の例に示すように、<index>
を使用してeclipselink-orm.xml
ディスクリプタに索引を作成することもできます。<column>
サブ要素を使用して列を定義します。@Index
注釈でサポートされるすべての属性は、<index>
要素でもサポートされます。
@InstantiationCopyPolicy
を使用して、エンティティにorg.eclipse.persistence.descriptors.copying.InstantiationCopyPolicy
を設定します。
使用方法
コピー・ポリシーによって、EclipseLinkが共有キャッシュとの間でオブジェクトをクローニングする方法が指定されます。@InstantiationCopyPolicy
によって、EclipseLinkは、オブジェクトをクローニングするために、オブジェクトの新規インスタンスを作成し、各永続属性をコピーします。代替メソッドには@CloneCopyPolicy
があり、これはオブジェクトをクローニングします。
クローニングは、新規インスタンスの作成よりも効率的で、一時属性値または非永続属性値を維持します。共有キャッシュに一時属性値または非永続属性値が必要ない場合は、@InstantiationCopyPolicy
を使用します。
デフォルトのEclipseLinkコピー・ポリシーは、構成によって異なります。
weaving.internal (およびフィールド・アクセス)を使用する場合、EclipseLinkはオブジェクトをコピーする特別なクローン・メソッドを生成します。
ウィービングを使用しない場合、EclipseLinkはインスタンス化を使用してオブジェクトをコピーします。
@InstantiationCopyPolicy
は、エンティティ、MappedSuperclassまたは埋込み可能エンティティに指定できます。
@JoinFetch
注釈を使用して、ソース・オブジェクトと同じ問合せにある関連オブジェクトの結合および読取りを有効にします。
注意: すべての問合せで結合が必要となるわけではないため、結合フェッチは問合せレベルで設定してください。 |
表2-28 @JoinFetchの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)この属性を、使用するフェッチの
|
|
使用方法
@JoinFetch
注釈は、次のマッピングに指定できます。
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
@ElementCollection
また、特にコレクション・リレーションシップには、より効率的なバッチ・フェッチを使用できます。
例
次の例では、@JoinFetch
注釈を使用して、従業員フィールドmanagedEmployees
を指定する方法を示します。
例2-52 @JoinFetch注釈の使用
@Entity
public class Employee implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="owner")
@JoinFetch(value=OUTER)
public Collection<Employee> getManagedEmployees() {
return managedEmployees;
}
...
}
例2-53に、eclipselink-orm.xml
ファイルでこの拡張を使用する方法を示します。
@JoinField
を使用して、NoSqlデータにマップされるオブジェクトの構造化データ型の外部キーを定義します。
表2-29 @JoinFieldの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)ソース・レコード内の外部キー/ID参照フィールドの名前 |
|
|
(オプション)ターゲット・レコード内のIDフィールドの名前 |
使用方法
@JoinField
注釈は、@JoinColumn
注釈の汎用形式であり、リレーショナル・データベースに固有ではありません。@JoinField
を使用して、EISおよびNoSQLデータをマップできます。
@MapKeyConvert
を使用して、対応するマップ済属性のキー列とともに使用される名前付きコンバータを指定します。
表2-31 @MapKeyConvertの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)使用するコンバータの名前
|
なし |
使用方法
@MapKeyConvert
を使用して、@MapKeyColumn
で使用されるキー値を変換し、データベース列とは異なる型または値を持つようにします。
@MapKeyConvert
注釈には、次の予約名があります。
serialized
: 関連付けられたマッピングでSerializedObjectConverter
を使用します。SerializedObjectConverter
を使用する場合、データベース表現はオブジェクトのシリアライズされたバージョンを保持するバイナリ・フィールドになり、オブジェクト・モデル表現は実際のオブジェクトになります。
class-instance
: 関連付けられたマッピングでClassInstanceConverterを使用します。ClassInstanceConverterを使用する場合、データベース表現はクラス名を表す文字列になり、オブジェクト・モデル表現は引数なしのコンストラクタで構築されたクラスのインスタンスになります。
none
: 関連付けられたマッピングにコンバータを配置しません。別のコンバータがデフォルトで設定されているか、または別のコンバータが設定されている状況をオーバーライドするために使用できます。
これらの予約名のいずれかを使用しない場合は、@Converter
注釈を使用してカスタム・コンバータを定義する必要があります。
例
例2-56に、@MapKeyConvert
注釈を使用して、コンバータをマップのキーに適用します。
例2-56 @MapKeyConvert注釈の使用
@Entity
public class Entity
…
@ElementCollection
@MapKeyColumn(name=”BANK”)
@Column(name=”ACCOUNT”)
@Convert(”Long2String”)
@MapKeyConvert(”CreditLine”)
public Map<String,Long> getCreditLines() {
return creditLines;
}
例2-57に、eclipselink-orm.xml
ファイルの<map-key-convert>
要素を使用する方法を示します。
例2-57 <map-key-convert> XMLの使用
<element-collection name="creditLines">
<map-key-convert>CreditLine</map-key-convert>
<map-key-column name="BANK"/>
<column name="ACCOUNT"/>
<convert>Long2String</convert>
<object-type-converter name="CreditLine">
<conversion-value data-value="RBC" object-value="RoyalBank"/>
<conversion-value data-value="CIBC" object-value="CanadianImperial"/>
<conversion-value data-value="SB" object-value="Scotiabank"/>
<conversion-value data-value="TD" object-value="TorontoDominion"/>
</object-type-converter>
<type-converter name="Long2String" data-type="String" object-type="Long"/>
<collection-table name="EMP_CREDITLINES">
<join-column name="EMP_ID"/>
</collection-table>
</element-collection>
@Multitenant
注釈は、指定のエンティティがアプリケーションの複数のテナント間で共有されることを指定します。マルチテナント・タイプは、これらのエンティティのデータを各テナントのデータベースに格納する方法を指定します。エンティティ・レベルまたはマップされたスーパークラス・レベルでマルチテナンシを指定できます。
使用方法
@Multitenant
注釈を使用する場合は、@Entity
または@MappedSuperclass
注釈とともにこの注釈を指定します。次に例を示します。
@Entity @Multitenant ... public class Employee() { ... }
次の3種類のマルチテナンシを使用できます。
例
例2-58に、@Multitenant
注釈の簡単な例を示します。この例では、PlayerエンティティにはデフォルトのPLAYER
表に格納された複数のテナントの行があり、デフォルトのTENANT_ID
列はデフォルトのコンテキスト・プロパティeclipselink.tenant-id
とともに識別子として使用されます。
例2-58 最小の@Multitenant注釈
@Entity @Multitenant public class Player { }
アプリケーションで共有のEntityManagerFactory
を使用し、EntityManager
をテナント固有にする場合、ランタイム・コードは次のようになります。
Map<String, Object> emProperties = new HashMap<String, Object>(); emProperties.set("eclipselink.tenant-id", "HTHL"); EntityManager em = emf.createEntityManager(emProperties);
詳細な例は、「単一表マルチテナンシ」、「テナントごとの表マルチテナンシ」および「VPDマルチテナンシ」を参照してください。
SINGLE_TABLE
マルチテナント・タイプは、エンティティまたはマップされたスーパークラスがマップする表に複数のテナントの行を含めることができることを指定します。テナント固有の行へのアクセスは、テナントに限定されます。
テナント固有の行は、テナント識別子列を使用することによってテナントに関連付けられます。識別子列は、アプリケーション・コンテキスト値とともに使用され、永続性コンテキストがアクセスできる対象を制限します。
マップされた表での問合せの結果は、プロパティ値として提供されるテナント識別子値に制限されます。これは、表のすべての挿入、更新および削除操作に適用されます。マルチテナント・メタデータがマップされたスーパークラス・レベルで適用される場合、サブエンティティによって独自のマルチテナント・メタデータが指定されていないかぎり、すべてのサブエンティティに適用されます。
注意: 単一表マルチテナンシのコンテキストでは、「単一表」は、複数のテナントが1つの表を共有できること、および各テナントのデータが識別子列によって他のテナントのデータと区別されることを意味します。単一表マルチテナンシとともに複数の表を使用できますが、その場合、エンティティの永続データは複数の表(Table およびSecondaryTable )に格納され、複数のテナントがすべての表を共有できます。 |
テナント識別子列を使用して単一表マルチテナンシを構成する方法の詳細は、「@TenantDiscriminatorColumn」を参照してください。
次の例では、@Multitenant
、@TenantDiscriminatorColumn
およびコンテキスト・プロパティを使用して、エンティティに単一表マルチテナンシを定義します。
例2-59 @Multitenantの使用例
@Entity @Table(name=”EMP”) @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumn(name = ”TENANT_ID”, contextProperty = "employee-tenant.id")
次の例では、<multitenant>
要素を使用して、最小の単一表マルチテナンシを指定します。SINGLE_TABLE
はデフォルト値のため、指定する必要はありません。
TABLE_PER_TENANT
マルチテナント・タイプは、エンティティの表(Table
およびSecondaryTable
)がテナント・コンテキストに基づいたテナント固有の表であることを指定します。これらの表へのアクセスは、指定のテナントに限定されます。結合表またはコレクション表を使用するエンティティ内のリレーションシップも、そのコンテキスト内に存在すると想定されます。
他のマルチテナント・タイプと同様に、エンティティ・レベルまたはマップされたスーパークラス・レベルで、テナントごとの表マルチテナンシを指定できます。エンティティ・レベルでは、トランザクションが開始した後、各エンティティ・マネージャでテナント・コンテキスト・プロパティを提供する必要があります。
テナントごとの表エンティティは、同じ永続性ユニット内の他のマルチテナント・タイプのエンティティと混在できます。
テナントのすべての読取り、挿入、更新および削除操作は、テナントの表にのみ適用されます。
テナントは、デフォルトで同じサーバー・セッションを共有します。各エンティティ・マネージャに対して、テナントごとの表の識別子を設定または更新する必要があります。ID生成は、テナントごとの表の方針に該当する、すべてのテナントで一意であると想定されます。
テナントごとの表マルチテナンシを構成する場合は、次を指定する必要があります。
ユーザーを特定するテナントごとの表のプロパティ。エンティティ・マネージャごとに設定するか、永続性ユニット当たりのテナントごとの表を分離するために、エンティティ・マネージャ・ファクトリで設定できます。
他のテナントの表からテナントの表を特定および分離するためのテナント表識別子。識別子タイプは、SCHEMA
、SUFFIX
およびPREFIX
です。テナント識別子タイプの詳細は、「@TenantTableDiscriminator」を参照してください。
次の例では、エンティティでテナントごとの表マルチテナンシを定義するために使用される@Multitenant
注釈を示します。@TenantTableDiscriminator(SCHEMA)
は、識別子表がスキーマによって特定されることを指定します。
例2-61 @Multitenantと@TenantTableDiscriminatorの使用例
@Entity @Table(name=”EMP”) @Multitenant(TABLE_PER_TENANT) @TenantTableDiscriminator(SCHEMA) public class Employee { ... }
次の例では、最小のテナントごとの表マルチテナンシを定義するために使用される<multitenant>
要素および<tenant-table-discriminator>
要素を示します。
VPD
(仮想プライベート・データベース)マルチテナンシ・タイプは、データベースがすべてのSELECT、UPDATEおよびDELETE問合せでテナントのフィルタリングを処理することを指定します。このタイプを使用する場合、永続性ユニットとともに使用されるプラットフォームでVPDがサポートされている必要があります。
EclipseLink VPDマルチテナンシを使用する場合、@Multitenant
および@TenantDiscriminatorColumn
を使用して、最初にデータベースでVPDを構成してから、エンティティまたはマップされたスーパークラスでマルチテナンシを指定する必要があります。
例2-63に、エンティティに定義されたVPDマルチテナンシを示します。前述のとおり、データベースのVPDもVPDマルチテナンシを有効にするように構成する必要があります。この場合、VPDデータベースは、USER_ID列を使用して指定クライアントによる指定行へのアクセスを制限するように構成されています。そのため、USER_ID
は、EclipseLinkマルチテナント操作のテナント識別子列としても指定されます。
@Entity @Multitenant(VPD) @TenantDiscriminatorColumn(name = "USER_ID", contextProperty = "tenant.id") @Cacheable(false) public class Task implements Serializable { ... ...
例は次のとおりです。
例2-64 <multitenant>の使用例
<entity class="model.Employee"> <multitenant type="VPD"> <tenant-discriminator-column name="USER_ID" context-property="tenant.id"/> </multitenant> <table name="EMPLOYEE"/> ... </entity>
関連項目
EclipseLinkソリューション・ガイドのマルチテナンシの使用に関する項
マルチテナントの例: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant
@Basic
マッピングで@Mutable
を使用して、複合フィールド・タイプの値を置換するのではなく、変更できる(または変更できない)かどうかを指定します。可変マッピングは、変更追跡のパフォーマンスに影響する場合があります。属性変更追跡は、非可変マッピングを使用する場合にのみウィービングできます。
使用方法
ほとんどの基本タイプ(int
、long
、float
、double
、String
、BigDecimal
など)は、可変ではありません。
デフォルトでは、Date
およびCalendar
タイプは可変ではないと想定されます。これらのタイプを可変にするには、@Mutable
注釈を使用します。グローバルな永続性プロパティeclipselink.temporal.mutable
を使用して、マッピングを可変として設定することもできます。
デフォルトでは、シリアライズされたタイプは可変と想定されます。@Mutable
注釈をfalse
に設定して、これらのタイプを可変でなくすることができます。
persistence.xml
ファイルにある永続性ユニットのDate
およびCalendar
フィールドの可変マッピングも構成できます。
例
例2-65に、@Mutable
注釈を使用してEmployee
フィールドのhireDate
を指定する方法を示します。
例2-65 @Mutable注釈の使用
@Entity
public class Employee implements Serializable {
...
@Temporal(DATE)
@Mutable
public Calendar getHireDate() {
return hireDate;
}
..
}
例2-66に、永続性ユニットのpersistence.xml
ファイルで、またはproperty
マップをインポートすることによって、可変マッピングを構成する方法を示します。
@NamedPLSQLStoredFunctionQuery
注釈を使用して、名前付き問合せとしてOracle PLSQLストアド・ファンクションをコールする問合せを定義します。
表2-35 @NamedPLSQLStoredFunctionQueryの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)ストアド・ファンクションの名前 |
|
|
(必須)このストアド・ファンクション問合せを参照する一意の名前 |
|
|
(必須)ストアド・ファンクションの戻り値 |
|
|
(オプション)問合せヒント |
|
|
(オプション)ストアド・ファンクションのパラメータ |
|
|
(オプション) |
使用方法
この注釈は、JDBCからアクセスできないRECORD
およびTABLE
などの複合PLSQLタイプのサポートを追加します。
@NamedPLSQLStoredFunctionQuery
は、エンティティまたはMappedSuperclassに指定できます。
例
例2-67に、この注釈を使用する方法を示します。
例2-67 @NamedPLSQLStoredFunctionQuery注釈の使用
@NamedPLSQLStoredFunctionQuery(
name="getEmployee",
functionName="EMP_PKG.GET_EMP",
returnParameter=@PLSQLParameter(
name="RESULT",
databaseType="EMP_PKG.EMP_TABLE"
)
)
@Embeddable
@Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME", "SALARY"})
@PLSQLRecord(
name="EMP_PKG.EMP_REC",
compatibleType="EMP_TYPE",
javaType=Employee.class,
fields={
@PLSQLParameter(name="F_NAME"),
@PLSQLParameter(name="L_NAME"),
@PLSQLParameter(
name="SALARY",
databaseType="NUMERIC_TYPE"
)
}
)
public class Employee { ...}
@NamedPLSQLStoredProcedureQueries
注釈を使用して、複数のNamedPLSQLStoredProcedureQuery
項目を定義します。
関連項目
詳細は、次を参照してください。
EclipseLinkの理解のストアド・プロシージャに関する項
Oracle PL/SQL http://www.oracle.com/technetwork/database/features/plsql/index.html
@NamedPLSQLStoredProcedureQuery
注釈を使用して、名前付き問合せとしてOracle PLSQLストアド・プロシージャをコールする問合せを定義します。
表2-37 @NamedPLSQLStoredProcedureQueryの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)ストアド・プロシージャの名前 |
|
|
(必須)このストアド・プロシージャ問合せを参照する一意の名前 |
|
|
(オプション)結果のクラス。 |
|
|
(オプション)問合せヒント |
|
|
(オプション)ストアド・プロシージャのパラメータ |
|
|
(オプション) |
使用方法
この注釈は、JDBCからアクセスできないRECORD
およびTABLE
などの複合PLSQLタイプのサポートを追加します。
@NamedPLSQLStoredProcedureQuery
は、エンティティ、埋込み可能またはMappedSuperclassに指定できます。
例
例2-69に、この注釈を使用する方法を示します。
例2-69 @NamedPLSQLStoredProcedureQuery注釈の使用
@NamedPLSQLStoredProcedureQuery( name="getEmployee", procedureName="MyStoredProcedure", functionName="EMP_PKG.GET_EMP", parameters={ @PLSQLParameter( name="EMP_OUT", direction=Direction.OUT, databaseType="EMP_PKG.EMP_REC" ) } ) @Embeddable @Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME", "SALARY"}) @OracleObject( name="EMP_PKG.EMP_REC", compatibleType="EMP_TYPE", javaType=Employee.class, fields={ @PLSQLParameter(name="F_NAME"), @PLSQLParameter(name="L_NAME"), @PLSQLParameter( name="SALARY", databaseType="NUMERIC_TYPE" ) } ) public class Employee { ...}
関連項目
詳細は、次を参照してください。
EclipseLinkの理解のストアド・プロシージャに関する項
Oracle PL/SQL http://www.oracle.com/technetwork/database/features/plsql/index.html
@NamedStoredFunctionQueries
注釈を使用して、複数のNamedStoredFunctionQuery
項目を定義します。
表2-38 @NamedStoredFunctionQueriesの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)名前付きストアド・プロシージャ問合せの配列 |
例
例2-70に、この注釈を使用する方法を示します。
例2-70 @NamedStoredFunctionQueries注釈の使用
@NamedStoredFunctionQueries{(
@NamedStoredFunctionQuery(
name="StoredFunction_In",
functionName="StoredFunction_In",
parameters={
@StoredProcedureParameter(direction=IN, name="P_IN", queryParameter="P_IN", type=Long.class)
},
returnParameter=@StoredProcedureParameter(queryParameter="RETURN", type=Long.class)
)
)}
複数の名前付きストアド・プロシージャをeclipselink-orm.xml
ファイルで定義する場合、複数の<named-stored-function_query>
要素のリストを作成します。
@NamedStoredFunctionQuery
を使用して、名前付き問合せとしてストアド・ファンクションをコールする問合せを定義します。
表2-39 @NamedStoredFunctionQueryの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)ストアド・ファンクションの名前 |
|
name |
(必須)このストアド・ファンクション問合せを参照する一意の名前 |
|
|
(必須)ストアド・ファンクションの戻り値 |
|
|
(オプション)ストアド・ファンクションを索引で、または名前でコールすることを指定します。
|
false |
|
(オプション)問合せヒント |
|
|
(オプション)ストアド・ファンクションのパラメータ |
|
|
(オプション)SQLResultMappingの名前 |
例
例2-71に、この注釈を使用する方法を示します。
例2-71 @NamedStoredFunctionQuery注釈の使用
@Entity
@Table(name="CMP3_ADDRESS")
@NamedStoredFunctionQuery(
name="StoredFunction_In",
functionName="StoredFunction_In",
parameters={
@StoredProcedureParameter(direction=IN, name="P_IN", queryParameter="P_IN", type=Long.class)
},
returnParameter=@StoredProcedureParameter(queryParameter="RETURN", type=Long.class)
)
public class Address implements Serializable {
...
}
例2-72に、eclipselink-orm.xml
ファイルの<named-stored-function-query>
要素を使用する方法を示します。
@NamedStoredProcedureQueries
注釈を使用して、複数のNamedStoredProcedureQuery
項目を定義します。
例
例2-73に、この注釈を使用する方法を示します。
例2-73 @NamedStoredProcedureQueries注釈の使用
@Entity
@Table(name="EMPLOYEE")
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(
name="ReadEmployeeInOut",
resultClass=org.eclipse.persistence.testing.models.jpa.customfeatures.Employee.class,
procedureName="Read_Employee_InOut",
parameters={
@StoredProcedureParameter(direction=IN_OUT, name="employee_id_v", queryParameter="ID", type=Integer.class),
@StoredProcedureParameter(direction=OUT, name="nchar_v", queryParameter="NCHARTYPE", type=Character.class)}
),
@NamedStoredProcedureQuery(
name="ReadEmployeeCursor",
resultClass=org.eclipse.persistence.testing.models.jpa.customfeatures.Employee.class,
procedureName="Read_Employee_Cursor",
parameters={
@StoredProcedureParameter(direction=IN, name="employee_id_v", queryParameter="ID", type=Integer.class),
@StoredProcedureParameter(direction=OUT_CURSOR, queryParameter="RESULT_CURSOR")})
})
public class Employee implements Serializable {
複数の名前付きストアド・プロシージャ問合せをeclipselink-orm.xml
ファイルで定義する場合、複数の<named-stored-procedure_query>
要素のリストを簡単に作成します。
@NamedStoredProcedureQuery
注釈を使用して、名前付き問合せとしてストアド・プロシージャをコールする問合せを定義します。
表2-41 @NamedStoredProcedureQueryの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)このストアド・プロシージャ問合せを参照する一意の名前 |
|
|
(必須)ストアド・プロシージャの名前。 |
|
|
(オプション)ストアド・プロシージャを名前でコールするかどうかを指定します。
|
|
|
(オプション)問合せヒントの配列 |
|
|
(オプション)ストアド・プロシージャが複数の結果セットを戻すかどうかを指定します。 これは、ストアド・プロシージャからの複数の結果セットをサポートしているデータベースにのみ適用されます。 |
|
|
(オプション)ストアド・プロシージャのパラメータの配列。 |
|
|
(オプション)結果のクラス。 |
|
|
(オプション) |
|
|
(オプション)ストアド・プロシージャが結果セットを保持するかどうかを指定します。 このことは、ストアド・プロシージャからの結果セットがサポートされているデータベースにのみ適用されます。 |
|
例
例2-74に、@NamedStoredProcedureQuery
を使用してストアド・プロシージャを定義する方法を示します。
例2-74 @NamedStoredProcedureQuery注釈の使用
@NamedStoredProcedureQuery(name="findAllEmployees", procedureName="EMP_READ_ALL", resultClass=Employee.class, parameters={
@StoredProcedureParameter(queryParameter="result", name="RESULT_CURSOR", direction=Direction.OUT_CURSOR})
@Entity
public class Employee {
...
}
例2-75に、eclipselink-orm.xml
ファイルの<named-stored-procedure-query>
要素を使用する方法を示します。
例2-75 <named-stored-procedure-query> XMLの使用
<named-stored-procedure-query name="SProcXMLInOut" result-class="Address" procedure-name="SProc_Read_XMLInOut">
<parameter direction="IN_OUT" name="address_id_v" query-parameter="ADDRESS_ID" type="Long"/>
<parameter direction="OUT" name="street_v" query-parameter="STREET" type="String"/>
</named-stored-procedure-query>
@Noncacheable
を使用して、リレーションシップのキャッシュ動作を構成します。リレーションシップで使用される場合、親エンティティがキャッシュされても、そのリレーションシップはキャッシュされません。
使用方法
EclipseLinkがエンティティを取得するたびに、リレーションシップはデータソースからリロードされます。リレーションシップのキャッシングが望ましくない状況において、または、異なるEclipseLinkキャッシュ・タイプを使用したり、参照をキャッシュしていることによって、異なるキャッシュ・スキームを使用する関連エンティティのキャッシュ存続期間が延長される場合に、このことが役立つことがあります。たとえば、エンティティAはエンティティBを参照し、エンティティAはFullで、エンティティBはWeakになります。リレーションシップのキャッシングを削除しない場合、エンティティBのキャッシュは、実質的にFullになります。
例
例2-76に、@Noncacheable
を使用して保護されたキャッシュを作成する方法を示します。
例2-76 @Noncacheable注釈の使用
@Entity
@Cache(
isolation=CacheIsolationType.PROTECTED
)
public class Employee {
@Id
private long id;
...
@OneToMany(mappedBy="manager")
@Noncacheable
private List<Employee> managedEmployees;
...
}
例2-77に、eclipselink-orm.xml
ファイルの<noncacheable>
XML要素の使用を示します。
例2-77 <noncacheable> XMLの使用
<?xml version="1.0"?>
<entity-mappings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"
version="2.4">
<entity name="Employee" class="org.acme.Employee" access="FIELD">
<cache isolation="PROTECTED"/>
<attributes>
<id name= "id"/>
<one-to-many name="managedEmployees" mapped-by="manager">
<noncacheable/>
</one-to-many>
</attributes>
</entity>
</entity-mappings
@NoSql
を使用して、リレーショナルでない(つまり、SQLではない)データソースを指定します。EclipseLinkは、非リレーショナル・データをオブジェクトにマップし、JPAを介してそのデータにアクセスできます。
表2-42 @NoSqlの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
エンティティ構造の名前。
|
|
|
(オプション)データがデータベース内に格納されるタイプ構造(データ形式)。
|
XML |
使用方法
dataFormat
は、使用されるNoSQLプラットフォームによって異なります。
MongoDBでは、MAPPED
を使用します。
Oracle NoSQLでは、MAPPED
(キー/値データ)またはXML
(単一XML文書の場合)を使用します。
XMLファイルおよびXMLメッセージングでは、XML
を使用します。
サポートされるデータ・ソース
EclipseLinkでは、JavaEE Connector Architecture CCI (Common Client Interface) APIを介した汎用NoSQLおよびEISデータソースと同様に、様々なNoSQLおよびEISプラットフォームがサポートされています。独自のEISPlatform
サブクラスおよびJCAアダプタも定義できます。
EclipseLinkでは、次のデータソースがサポートされています。
MongoDB
Oracle NoSQL
XMLファイル
JMS
Oracle AQ
例
例2-78に、XMLデータソースとの@NoSql
の使用を示します。
例2-78 @NoSql注釈とXMLの使用
@Entity @NoSql(dataType="order") public class Order { @Id @GeneratedValue @Field(name="@id") private long id; @Basic @Field(name="@description") private String description; @Embedded @Field(name="delivery-address") private Address deliveryAddress @ElementCollection @Field(name="orderLines/order-line") private List<OrderLine> orderLines; @ManyToOne @JoinField(name="customer-id") private Customer customer; } @Embeddable @NoSql public class OrderLine { @Field(name="@line-number") private int lineNumber; @Field(name="@item-name") private String itemName; @Field(name="@quantity") private int quantity; }
これにより、次のXMLデータが作成されます。
<order id="4F99702B271B1948027FAF06" description="widget order"> <deliveryAddress street="1712 Hasting Street" city="Ottawa" province="ON" postalCode="L5J1H5"/> <order-lines> <order-line lineNumber="1" itemName="widget A" quantity="5"/> <order-line lineNumber="2" itemName="widget B" quantity="1"/> <order-line lineNumber="3" itemName="widget C" quantity="2"/> <order-lines> <customer-id>4F99702B271B1948027FAF08</customer-id> <order>
例2-79に、JSONデータソースとの@NoSql
の使用を示します。
例2-79 @NoSql注釈とJSONの使用
@Entity @NoSql(dataType="orders", dataFormat=DataFormatType.MAPPED) public class Order { @Id @GeneratedValue @Field(name="_id") private long id; @Basic @Field(name="description") private String description; @Embedded @Field(name="deliveryAddress") private Address deliveryAddress @ElementCollection @Field(name="orderLines") private List<OrderLine> orderLines; @ManyToOne @JoinField(name="customerId") private Customer customer; } @Embeddable @NoSql(dataFormat=DataFormatType.MAPPED) public class OrderLine { @Field(name="lineNumber") private int lineNumber; @Field(name="itemName") private String itemName; @Field(name="quantity") private int quantity; }
これにより、次のJSONドキュメントが作成されます。
{ "_id": "4F99702B271B1948027FAF06", "description": "widget order", "deliveryAddress": { "street": "1712 Hasting Street", "city": "Ottawa", "province": "ON", "postalCode": "L5J1H5", }, "orderLines": [ {"lineNumber": "1", "itemName": "widget A", "quantity": "5"}, {"lineNumber": "2", "itemName": "widget B", "quantity": "1"}, {"lineNumber": "3", "itemName": "widget C", "quantity": "2"} ], "customerId": "4F99702B271B1948027FAF08", }
@ObjectTypeConverter
注釈は、マップ済属性の読取りおよび書込み中にデータベース・データ値の固定数をJavaオブジェクト値に変換するorg.eclipse.persistence.mappings.converters.ObjectTypeConverter
を指定します。
表2-43 @ObjectTypeConverterの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
この属性をコンバータの |
なし |
|
(オプション)この属性をデータベースに格納されるタイプに設定します。 |
|
|
(オプション)この属性の値をエンティティに格納されるタイプに設定します。 |
|
|
この属性の値を変換値( |
なし |
|
この属性の値をデフォルトのオブジェクト値に設定します。この引数はデータ値がない場合にレガシー・データを処理するためのものであることに注意してください。 |
空の |
脚注 1 デフォルトは、永続性フィールドまたはプロパティのタイプから推測されます。
例
例2-80に、@ObjectTypeConverter
注釈を使用してgender
フィールドのオブジェクト・コンバータを指定する方法を示します。
例2-80 @ObjectTypeConverter注釈の使用
public class Employee implements Serializable{ ... @ObjectTypeConverter ( name="genderConverter", dataType=java.lang.String.class, objectType=java.lang.String.class, conversionValues={ @ConversionValue(dataValue="F", objectValue="Female"), @ConversionValue(dataValue="M", objectValue="Male")} ) @Convert("genderConverter") public String getGender() { return gender; } ... }
例2-81に示すように、ソース・コードで@ObjectTypeConverter
注釈を使用するかわりにデプロイメント・ディスクリプタで<object-type-converter>
要素を使用できます。
@ObjectTypeConverters
を使用して、複数のObjectTypeConverter
項目を定義します。
例
例2-82に、この注釈を使用する方法を示します。
例2-82 @ObjectTypeConverters注釈の使用
@Entity(name="Employee")
@Table(name="CMP3_FA_EMPLOYEE")
@ObjectTypeConverters({
@ObjectTypeConverter(
name="sex",
dataType=String.class,
objectType=org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee.Gender.class,
conversionValues={
@ConversionValue(dataValue="F", objectValue="Female"),
@ConversionValue(dataValue="M", objectValue="Male")
}
)
})
複数のオブジェクト・タイプ・コンバータをeclipselink-orm.xml
ファイルで定義するには、複数の<object-type-converter>
要素のリストを作成するだけです。
@OptimisticLocking
を使用して、エンティティを更新または削除する際にEclipseLinkが使用するオプティミスティック・ロックのタイプを指定します。
表2-45 @OptimisticLockingの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション) オプティミス・ロック・ポリシーがロックをカスケードする必要のある場所を指定します。私有および孤立の削除オブジェクトを変更すると、EclipseLinkでバージョンが更新されます。 この要素は現在、 |
|
|
(オプション)オプティミスティックにロックされる列のリストを指定します。 この要素は、 |
|
|
(オプション)使用するオプティミスティック・ロック・ポリシーのタイプは、次のとおりです。
|
|
@OracleArray
注釈を使用して、Oracle DatabaseのVARRAY
タイプを定義します。これはPLSQLプロシージャ・コール内で使用できます。
例
例2-85に、@OracleArray
注釈を使用してVARRAY
タイプを定義する方法を示します。
例2-85 @OracleArray注釈の使用
@NamedPLSQLStoredFunctionQuery( name="getEmployee", functionName="EMP_PKG.GET_EMP", parameters={ @PLSQLParameter( name="EMP_OUT", direction=Direction.OUT, databaseType="EMP_PKG.EMP_REC" ) } ) @Embeddable @Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME","SALARY"}) @OracleArray( name="EMP_PKG.EMP_REC", nestedType=VARCHAR_TYPE javaType=Employee.class, ) public class Employee{...}
この例を確認して、変更が必要な点をご連絡ください。
@OracleObject
注釈を使用して、Oracle DatabaseのOBJECT
タイプを定義します。これはPLSQLプロシージャ・コール内で使用できます。
例
例2-86に、@OracleObject
注釈を使用してOracle OBJECT
タイプを定義する方法を示します。
例2-86 @OracleObject注釈の使用
@NamedPLSQLStoredFunctionQuery( name="getEmployee", functionName="EMP_PKG.GET_EMP", parameters={ @PLSQLParameter( name="EMP_OUT", direction=Direction.OUT, databaseType="EMP_PKG.EMP_REC" ) } ) @Embeddable @Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME","SALARY"}) @OracleObject( name="EMP_PKG.EMP_REC", javaType=Employee.class, fields={ @PLSQLParameter(name="F_NAME"), @PLSQLParameter(name="L_NAME"), @PLSQLParameter( name="SALARY", databaseType="NUMERIC_TYPE" ) } ) public class Employee{...}
@OrderCorrection
を使用して、データベースから読み取られた順序リストが無効な場合(たとえば、Null、重複、負の値、またはリスト・サイズ以上の値がある場合)に使用する方針を指定します。
有効にするには、n要素の順序リストは{0, 1,..., n-1}
である必要があります。
表2-50 @OrderCorrectionの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
value |
(オプション)データベースから読み取られた順序リストが無効な場合に使用する方針を指定します。
|
|
使用方法
@OrderCorrection
を使用すると、EclipseLinkが無効なリストの順序を処理する方法を指定できます。
EXCEPTION
: OrderCorrectionType=EXCEPTION
の場合、EclipseLinkはリストを修正しません。かわりに、EclipseLinkは、エラー・コードQueryException.LIST_ORDER_FIELD_WRONG_VALUE
でQueryException
をスローします。
たとえば、データベースに次の3つのオブジェクトのリストがあるとします。
{null, objectA}; {2, objectB}, {5, ObjectC};
アプリケーションに読み取る際、EclipseLinkは例外をスローします。
READ
: OrderCorrectionType=READ
の場合、EclipseLinkはアプリケーションに読み取られたリストを修正しますが、データベースに残る無効なリストの順序に関する情報は保持しません。これは、リストを読取り専用で使用する場合は問題になりませんが、リストを変更してデータベースに保存する場合は、順序がキャッシュとは異なり、無効になる可能性が高くなります。
READ
モードは、マップ済属性がList
ではない場合にデフォルトとして使用されます。
たとえば、データベースに次の3つのオブジェクトのリストがあるとします。
{null, objectA}; {2, objectB}, {5, ObjectC}
リストとして読み取られる場合: {objectA, objectB, objectC}
新しい要素をリストに追加する場合: {objectA, objectB, objectC, objectD}
更新したリストをデータベースに保存する場合: {null, objectA}, {2, objectB}, {5, objectC}, {3, objectD}
リストを再度読み取る場合: {objectA, objectB, objectD, objectC}
READ_WRITE
: OrderCorrectionType=READ_WRITE
の場合、EclipseLinkは、アプリケーションに読み取られるリストの順序を修正し、データベースに残った無効なリストの順序を記憶します。リストが更新されてデータベースに保存される場合、順序索引はデータベースのリスト順序がキャッシュ内とまったく同じになるように保存されます(そのため、有効になります)。
READ_WRITE
モードは、マップ済属性がList
またはVector
のいずれか(つまり、EclipseLinkの内部クラスIndirectList
から割当て可能)の場合にデフォルトとして使用されます。JPAでは、モードが指定されなければ、READ_WRITE
がデフォルトとして使用されます。
たとえば、データベースに次の3つのオブジェクトのリストがあるとします。
{null, objectA}; {2, objectB}, {5, ObjectC}
リストとして読み取られる場合: {objectA, objectB, objectC}
新しい要素をリストに追加する場合: {objectA, objectB, objectC, objectD}
更新したリストをデータベースに保存する場合: {0, objectA}, {1, objectB}, {2, objectC}, {3, objectD}
リストを再度読み取る場合: {objectA, objectB, objectC, objectD}
@Partitioned
を使用して、エンティティまたはリレーションシップに使用するパーティション・ポリシーを指定します。
使用方法
パーティション化を使用して、複数のデータベースまたはデータベース・クラスタ(Oracle RACなど)間にあるクラスのデータをパーティション化します。パーティション化することで、複数のデータベース・マシンが要求に応えることができるようになり、スケーラビリティを向上できます。
エンティティ、リレーションシップ、問合せ、またはセッション/永続性ユニットで@Partitioned
を指定できます。
パーティション・ポリシー
データのパーティション化を構成するには、@Partitioned
注釈および1つ以上のパーティション・ポリシーの注釈を使用します。様々な種類のポリシーを定義する注釈は、次のとおりです。
@HashPartitioning
: オブジェクト(オブジェクトのID、場所、テナントなど)からのフィールド値のハッシュによって、データベース・クラスタへのアクセスをパーティション化します。ハッシュによって、接続プール/ノードのリストに索引が付けられます。ハッシュ値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにハッシュがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@PinnedPartitioning
: 単一の接続プール/ノードへの要求を固定します。これにより、垂直パーティションが可能になります。
@RangePartitioning
: オブジェクト(オブジェクトのID、場所、テナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。各サーバーは、値の範囲に割り当てられます。その値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@ReplicationPartitioning
: 要求を一連の接続プール/ノードに送信します。このポリシーは、データベース・マシンのクラスタ間でデータをレプリケートするためのものです。変更問合せのみがレプリケートされます。
@RoundRobinPartitioning
: 要求をラウンドロビン方式で一連の接続プール/ノードに送信します。これは、データベース・マシンのクラスタ間で読取り問合せをロード・バランシングするためのものです。パーティション化をサポートしていないため、すべてのデータベースを各マシンでレプリケートする必要があります。データを読取り専用にするか、書込みをレプリケートする必要があります。
@UnionPartitioning
: 問合せをすべての接続プールに送信し、結果を統合します。これは、パーティション・リレーションシップ間のManyToMany
など、パーティション化を使用する際にパーティションに及ぶ問合せまたはリレーションシップのためのものです。
@ValuePartitioning
: オブジェクト(オブジェクトの場所またはテナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。各値は、特定のサーバーに割り当てられます。その値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@Partitioning
: カスタム・パーティション・ポリシーによって、データベース・クラスタへのアクセスをパーティション化します。PartitioningPolicyクラスを指定および実装する必要があります。
パーティション・ポリシーは、永続性ユニットでグローバルに名付けられたオブジェクトで、複数のディスクリプタまたは問合せ間で再利用できます。特にJPA注釈とXMLを使用することによって、構成のユーザビリティが向上します。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
クラスタ化されたデータベースとOracle RAC
一部のデータベースでは、複数のマシン全体にわたるデータベースのクラスタリングがサポートされます。Oracle RACでは、単一のデータベースを複数の異なるサーバー・ノードに拡張できます。Oracle RACでは、表およびノードでデータのパーティション化もサポートされます。データベース・クラスタでは、クラスタ内の任意のノードからどのデータにもアクセスできます。ただし、一般的に、特定ノードへのデータ・アクセスをパーティション化し、ノード間の通信を削減することがより効率的です。
EclipseLinkのパーティション化をクラスタ・データベースと組み合せると、ノード間通信を減少させ、スケーラビリティを向上できます。
データベース・クラスタとともにパーティション化を使用する場合に必要なことは、次のとおりです。
データベース・クラスタによってすべてのノードにデータを使用できるようになるため、パーティション・ポリシーでレプリケーションを有効にしないでください。
データベース・クラスタはすべてのノードから完全な問合せ結果を戻すため、パーティション・ポリシーで統合を使用しないでください。
データ・ソースおよびEclipseLinkの接続プールは、クラスタ内のノードごとに定義する必要があります。
各トランザクションが単一ノードへのアクセスのみを必要とするように、アプリケーションのデータ・アクセスおよびデータのパーティション化を設計する必要があります。
1つのトランザクションに複数のノードが含まれないようにするために、また2フェーズ・コミットを回避するために、EntityManagerの排他接続の使用をお薦めします。
例
例2-89に、従業員データを場所別にパーティション化する方法を示します。2つのプライマリ・サイト(オタワおよびトロント)は、異なるデータベースにそれぞれ格納されます。他のすべての場所は、デフォルトのデータベースに格納されます。プロジェクトは、例2-90に示すとおり、IDでレンジ・パーティション化されます。ID値の各範囲は、異なるデータベースに格納されます。従業員/プロジェクト・リレーションシップは、パーティション間リレーションシップの例です。従業員とプロジェクトを異なるデータベースに格納できるようにするには、統合ポリシーを使用して、統合表を各データベースにレプリケートします。
例2-89 パーティション化の使用
@Entity @IdClass(EmployeePK.class) @UnionPartitioning( name="UnionPartitioningAllNodes", replicateWrites=true) @ValuePartitioning( name="ValuePartitioningByLOCATION", partitionColumn=@Column(name="LOCATION"), unionUnpartitionableQueries=true, defaultConnectionPool="default", partitions={ @ValuePartition(connectionPool="node2", value="Ottawa"), @ValuePartition(connectionPool="node3", value="Toronto") }) @Partitioned("ValuePartitioningByLOCATION") public class Employee { @Id @Column(name = "EMP_ID") private Integer id; @Id private String location; ... @ManyToMany(cascade = { PERSIST, MERGE }) @Partitioned("UnionPartitioningAllNodes") private Collection<Project> projects; ... }
例2-90 @RangePartitioningの使用
@Entity @RangePartitioning( name="RangePartitioningByPROJ_ID", partitionColumn=@Column(name="PROJ_ID"), partitionValueType=Integer.class, unionUnpartitionableQueries=true, partitions={ @RangePartition(connectionPool="default", startValue="0", endValue="1000"), @RangePartition(connectionPool="node2", startValue="1000", endValue="2000"), @RangePartition(connectionPool="node3", startValue="2000") }) @Partitioned("RangePartitioningByPROJ_ID") public class Project { @Id @Column(name="PROJ_ID") private Integer id; ... }
@Partitioning
を使用して、カスタムPartitioningPolicy
を構成します。
表2-52 @Partitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
|
|
(必須) |
使用方法
データのパーティション化により、アプリケーションは1つ以上のデータベース・マシン間でデータを増減できます。EclipseLinkでは、エンティティ・レベルでデータ・パーティション化がサポートされ、同じクラスのエンティティ・インスタンスの異なるセットを、異なる物理データベースまたはデータベース・クラスタ内の異なるノードに格納できます。通常のデータベースとクラスタ化されたデータベースの両方がサポートされています。データは、水平方向と垂直方向の両方でパーティション化できます。
エンティティ、リレーションシップ、問合せまたは永続性ユニットでパーティション化を有効にできます。
例
例2-91に、カスタム・パーティション・ポリシーを示します。
例2-91 @Partitioning注釈の使用
@Entity
@Partitioning(name="order", partitioningClass=OrderPartitioningPolicy.class)
@public class Order {
...
}
public class OrderPartitioningPolicy extends PartitioningPolicy {
public List<Accessor> getConnectionsForQuery(AbstractSession session, DatabaseQuery query, AbstractRecord arguments) {
List<Accessor> accessors = new ArrayList<Accessor>(1);
accessors.add(getAccessor(ACMEPool.leastBusy(), session, query, false));
return accessors;
}
}
@PinnedPartitionPolicy
を使用して、単一の接続プールへの要求を固定し、垂直パーティションを可能にします(つまり、エンティティ、問合せまたはセッションが常に単一データベースにアクセスするようにします)。
表2-53 @PinnedPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
問合せを固定する接続プールの名前 |
|
|
パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
使用方法
パーティション・ポリシーは、再利用できるようにグローバルに名付けられます。@Partitioned
注釈を使用してパーティション・ポリシーを設定する必要もあります。
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットで@PinnedPartitioning
を指定できます。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
NamedPLSQLStoredProcedureQuery
注釈またはPLSQLRecord
注釈内で@PLSQLParameter
を使用します。
表2-54 @PLSQLParameterの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)問合せパラメータ名。 |
|
|
(オプション)ストアド・プロシージャ・パラメータの方向。
|
|
|
(オプション)パラメータのデータベース・データ型。 |
|
|
(オプション)フィールド値の最大長 |
|
|
(オプション)ストアド・プロシージャ・パラメータの名前。 |
|
|
(オプション)パラメータが必須かオプションか、プロシージャでデフォルト設定されるかどうかを指定します。 |
|
|
(オプション)最大精度値 |
|
|
(オプション)最大精度値 |
@PLSQLRecord
を使用して、PLSQLプロシージャ内で使用するデータベースPLSQL RECORD
タイプを定義します。
表2-55 @PLSQLRecordの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)データベースの表の名前 |
|
|
(必須)レコードの構造をミラーリングするデータベース |
|
|
(必須)レコード・タイプのフィールド |
|
|
(オプション)オブジェクト・タイプのクラス |
使用方法
Oracle PLSQL RECORD
タイプは、構造化されたデータベース・タイプです。JDBCはこれらのタイプを戻すメカニズムを提供していませんが、EclipseLinkはこれらのタイプからOBJECT
タイプへの変換をサポートしています。データベースでOBJECT
タイプを作成してRECORD
タイプをミラーリングし、@PLSQLRecord
のcompatibileType
として提供する必要があります。
RECORD
をJavaクラスにマップしたり、Javaクラスを@Embeddable
としてマップしたり、@Struct
注釈を使用してRECORD
タイプをミラーリングするOBJECT
タイプにJavaクラスをマップすることができます。
PLSQLストアド・プロシージャ問合せに対するパラメータとして、Javaクラスをコールしたり戻すことができます。
例
例2-92に、この注釈を使用する方法を示します。
例2-92 @PLSQLRecord注釈の使用
@NamedPLSQLStoredFunctionQuery(name="getEmployee", functionName="EMP_PKG.GET_EMP", returnParameter=@PLSQLParameter(name="RESULT", databaseType="EMP_PKG.EMP_REC")) @Embeddable @Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME", "SALARY"}) @PLSQLRecord(name="EMP_PKG.EMP_REC", compatibleType="EMP_TYPE", javaType=Employee.class, fields={@PLSQLParameter(name="F_NAME"), @PLSQLParameter(name="L_NAME"), @PLSQLParameter(name="SALARY", databaseType="NUMERIC_TYPE")}) public class Employee { ... }
関連項目
詳細は、次を参照してください。
EclipseLinkの理解のストアド・プロシージャに関する項
Oracle PL/SQL http://www.oracle.com/technetwork/database/features/plsql/index.html
@PLSQLRecords
を使用して、複数のPLSQLRecord
を定義します。
関連項目
詳細は、次を参照してください。
EclipseLinkの理解のストアド・プロシージャに関する項
Oracle PL/SQL http://www.oracle.com/technetwork/database/features/plsql/index.html
@PLSQLTable
注釈を使用して、データベースのPLSQL TABLE
タイプを定義します。これはPLSQLプロシージャ・コール内で使用できます。
表2-57 @PLSQLTableの注釈要素
要素 | 説明 | デフォルト |
---|---|---|
name |
(必須)データベースの表タイプの名前 |
|
compatibilityType |
(必須)表構造をミラーするデータベース |
|
nestedType |
(必須)表のタイプ( |
|
javaType |
(オプション) |
|
isNestedTable |
(オプション)非連想(ネストした)表を指定します。通常、この方法は、PL/SQLでコレクションのコンストラクタを生成する場合に使用します。連想配列( |
|
例
例2-93 @PLSQLTable注釈の使用
@Named PLSQLStoredProcedureQuery( name="getEmployee", functionName="EMP_PKG.GET_EMP", parameters={ @PLSQLParamter( name="EMP_OUT", direction=Direction.OUT, databaseType="EMP_TABLE" ) } ) @Embeddable @Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME", "SALARY"}) @PLSQLTable( name="EMP_PKG.EMP_TABLE", compatibilityType="EMP_VARRAY", nestedType="EMP_REC" ) public class Employee{...}
@PrimaryKey
を使用して、IDの拡張構成を可能にします。
検証ポリシーを指定して、ゼロが有効なID値かどうかを指定できます。主キー列のセットも明確に指定できます。
表2-59 @PrimaryKeyの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)キャッシュにオブジェクトを格納するキャッシュ・キー・タイプを構成します。このタイプには、単純なシングルトンIDの基本ID値または最適化されたCachedIdタイプを指定できます。この要素は次の値を受け取ります。
|
|
|
(オプション)主キー列を直接指定します。主キーに外部キー、継承識別子フィールド、埋込みフィールド、トランスフォーメーション・マップ済フィールドなどの基本以外のフィールドが含まれる場合、 |
|
|
(オプション)実行されるID検証を構成します。
デフォルトでは、 |
|
使用方法
デフォルトで、EclipseLinkは、nullを使用できないプリミティブ型(int
やlong
など)で0をnull
として解釈するため、0は主キーにとって無効な値となります。@PrimaryKey
注釈を使用してエンティティ・クラスに対してIdValidation
を構成することによって、この設定を変更できます。eclipselink.id-validation
プロパティを使用して、永続性ユニット全体に対してIdValidation
を構成します。
validation
要素を設定すると、EclipseLinkがIDを生成する方法にも影響します。新規IDは、無効なID(デフォルトでは、null
または0
)に対してのみ生成されます。NONE
に設定すると、IDの生成が無効になります。
@PrivateOwned
を使用して、リレーションシップが私有されることを指定します。ターゲット・オブジェクトは、ソース・オブジェクトの依存部分であり、その他のオブジェクトから参照されず、単独では存在できません。
使用方法
@PrivateOwned
を使用すると、多くの操作が、削除、挿入、リフレッシュ、ロック(カスケードされる場合)を含むリレーションシップ間でカスケードされます。コレクションから除去されるプライベート・オブジェクトが削除され、追加されるオブジェクトが挿入されたことも確認します。
@OneToOne
、@OneToMany
および@VariableOneToOne
注釈とともに@PrivateOwned
を指定できます。私有は、@BasicCollection
および@BasicMap
注釈で暗黙的に示されます。
参照先のオブジェクトが私有されている場合、参照先の子オブジェクトは親オブジェクトなしでは存在できません。
追加情報
リレーションシップが私有されていることを示すと、次のことを示していることになります。
私有されたリレーションシップのソースが削除されると、EclipseLinkはターゲットを削除します。これは、@CascadeOnDeleteの設定に相当します。
ソースからのターゲットの参照が削除されると、EclipseLinkはターゲットを削除します。
通常、共有される可能性のあるオブジェクトに私有されたリレーションシップは構成しないでください。オブジェクトがプライベートに所有されたリレーションシップでターゲットになっている場合は、そのオブジェクトを複数のリレーションシップでターゲットにしないでください。
注意: 私有されたオブジェクトへの参照を「クリーンアップ」することはアプリケーションの責任になるため、私有されたオブジェクトを参照すると望ましくない影響が生じる可能性があります。オブジェクトを参照解除して削除すると、削除されたオブジェクトを引き続き参照するキャッシュ内のその他のオブジェクトによって制約違反が発生したり、オブジェクトが復活したり(カスケード永続化を使用する場合)、データベースの内容が反映されなくなる可能性があります。 |
@Property
を使用して、マップ済属性またはget
/set
メソッドに単一のユーザー定義済プロパティを指定します。@Properties
注釈を使用して、複数のプロパティをラップします。
EclipseLinkでは使用されませんが、アプリケーションまたは拡張機能でEclipseLinkメタデータを拡張する必要がある場合は、マッピング・プロパティを指定できます。
使用方法
エンティティ、MappedSuperclassまたは埋込みクラス内のマップ済属性(またはget
/set
メソッド)に@Property
を指定できます。エンティティ、MappedSuperclassまたは埋込み可能クラスにもこの注釈を指定できます。
MappedSuperclassに定義されたプロパティは、すべての継承エンティティおよびMappedSuperclassに渡されます。競合する場合は、クラスに直接定義されたプロパティがクラスの親から継承された値よりも常に優先されます。
orm.xml
マッピング・ファイルを使用すると、EclipseLinkは、マップ済属性の注釈で指定された@Property
および@Properties
を無視します。クラスの注釈は、orm.xml
ファイルに指定された注釈にマージされ、競合している場合はファイルに指定された注釈が優先されます。
@Property
を使用して、マップ済属性またはget
/set
メソッドに単一のユーザー定義済プロパティを指定します。@Properties
注釈を使用して、複数のプロパティをラップします。
表2-61 @Propertyの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)プロパティの名前。 |
|
|
(必須)プロパティの |
|
|
(オプション)プロパティの値タイプ。 |
|
使用方法
エンティティ、MappedSuperclassまたは埋込みクラス内のマップ済属性(またはget
/set
メソッド)に@Property
を指定できます。エンティティ、MappedSuperclassまたは埋込み可能クラスにもこの注釈を指定できます。
MappedSuperclassに定義されたプロパティは、すべての継承エンティティおよびMappedSuperclassに渡されます。競合する場合は、クラスに直接定義されたプロパティがクラスの親から継承された値よりも常に優先されます。
orm.xml
マッピング・ファイルを使用すると、EclipseLinkは、マップ済属性の@Property
注釈および@Properties
注釈を無視します。クラスの注釈は、orm.xml
ファイルに指定された注釈にマージされ、競合している場合はファイルに指定された注釈が優先されます。
@QueryRedirectors
を使用して、前処理および後処理、リダイレクト、または監査などの一部の副次的影響の実行に対するEclipseLink問合せをインターセプトします。
注釈要素
表2-62は、この注釈の要素を示しています。
表2-62 @QueryRedirectorsの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
この |
|
|
デフォルトの |
|
insert |
デフォルトの |
|
readAll |
デフォルトの
|
|
|
デフォルトの
|
|
|
デフォルトの 集計関数を含む、または複数のエンティティを選択するJPA問合せを実行しているユーザーの場合、このリダイレクタが起動されます。 |
|
|
デフォルトの |
|
使用方法
@QueryRedirectors
を使用して、標準のEclipseLink問合せ機能を拡張します。
QueryRedirector
を問合せヒントeclipselink.query.redirector
を介して設定するか、エンティティのデフォルトのリダイレクタとして設定できます。
QueryRedirectors
は、TopLink Gridを統合して、問合せをCoherence Gridにリダイレクトする際に使用されます。
@RangePartitioning
を使用して、オブジェクト(オブジェクトのID、場所、テナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。
EclipseLinkは、各サーバーに値の範囲を割り当てます。サーバーの値を持つオブジェクトに対するすべての書込みまたは読取り要求は、特定サーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
注釈要素
表2-64は、この注釈の要素を示しています。
表2-64 @RangePartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)パーティション・ポリシーの名前。永続性ユニット内に対して一意である必要があります。 |
|
|
(必須)問合せをパーティション化するためのデータベース列または問合せパラメータ。これは表列名であり、クラス属性名ではありません。列値は、問合せに含まれている必要があり、通常はオブジェクトIDの一部です。 これは、問合せパラメータの名前にもなります。問合せにフィールドが含まれていない場合、問合せはパーティション化されません。 |
|
|
(必須)パーティション化する接続プール名のリスト |
|
|
開始値および終了値のタイプ |
|
|
パーティション・フィールドを含まない問合せをすべてのデータベースに送信し、結果を統合するかどうかを定義します。 |
|
使用方法
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットでパーティション化を有効にできます。
パーティション・ポリシーは、再利用できるようにグローバルに名付けられ、@Partitioned
注釈を使用して設定される必要もあります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
例
例2-98に、@RangePartitioning
注釈を使用する方法を示します。
例2-98 @RangePartitioning注釈の使用
@Entity
@Table(name="PART_PROJECT")
@RangePartitioning(
name="RangePartitioningByPROJ_ID",
partitionColumn=@Column(name="PROJ_ID"),
partitionValueType=Integer.class,
unionUnpartitionableQueries=true,
partitions={
@RangePartition(connectionPool="default", startValue="0", endValue="1000"),
@RangePartition(connectionPool="node2", startValue="1000", endValue="2000"),
@RangePartition(connectionPool="node3", startValue="2000")
})
@Partitioned("RangePartitioningByPROJ_ID")
public class Project implements Serializable {
...
}
例2-98に、eclipselink-orm.xml
ファイルの<range-partitioning>
要素を使用する方法を示します。
例2-99 <range-partitioning> XMLの使用
<entity name="Project" class="Project" access="FIELD">
<table name="PART_PROJECT"/>
<range-partitioning name="RangePartitioningByPROJ_ID" partition-value-type="java.lang.Integer" union-unpartitionable-queries="true">
<partition-column name="PROJ_ID"/>
<partition connection-pool="default" start-value="0" end-value="1000"/>
<partition connection-pool="node2" start-value="1000" end-value="2000"/>
<partition connection-pool="node3" start-value="2000"/>
</range-partitioning>
<partitioned>RangePartitioningByPROJ_ID</partitioned>
</entity>
@ReadOnly
を使用して、クラスが読取り専用であることを指定します。
使用方法
エンティティまたはMappedSuperclassに定義できます。
継承の場合、@ReadOnly
注釈は継承階層のルートにのみ定義できます。
@ReadOnly
を使用し、EclipseLinkの永続性コンテキストをバイパスしてヒープ領域を節約することもできます(大規模データセットをロードする必要がある場合など)。
注意: 読取り専用エンティティは変更しないでください。変更すると、EclipseLinkのキャッシュが破損する可能性があります。読取り専用エンティティを変更するには、クローニングまたはシリアライズされる必要があります。 |
トランスフォーメーション・マッピングとともに@ReadTransformer
を使用して、データベース列値から属性値への変換を定義します(マッピングが書込み専用ではない場合)。
注釈要素
表2-65は、この注釈の要素を示しています。
表2-65 @ReadTransformerの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
マップされるクラスにはこの名前を持つメソッドが必要で、(属性に値を割り当てるのではなく)属性に割り当てられる値を戻します。 |
|
transformerClass |
クラスはインスタンス化され、その |
|
注意: method またはtransformerClass のいずれか(両方ではない)を指定する必要があります。 |
@ReplicationPartitioning
を使用して、要求を一連の接続プールに送信します。これは、データベース・マシンのクラスタ間でデータをレプリケートするためのものです。変更問合せのみがレプリケートされます。
表2-66 @ReplicationPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
パーティション・ポリシーの名前。永続性ユニット内に対して一意である必要があります。 |
|
|
レプリケートする接続プール名のリスト |
|
使用方法
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットでパーティション化を有効にできます。
パーティション・ポリシーは、再利用できるようにグローバルに名付けられ、@Partitioned
注釈を使用して設定される必要もあります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
@ReturnInsert
を使用して、INSERT
操作で書込み中のオブジェクトに値を戻します。これにより、表のデフォルト値、トリガー、またはストアド・プロシージャの計算された値をオブジェクトに戻して設定できます。
注意: 戻りは、Oracle Databaseでのみサポートされ、INSERT RETURNING 句が必要です。
他のデータベースで戻りを使用する場合、出力パラメータを持つストアド・プロシージャを挿入問合せに使用します。 |
表2-67 @ReturnInsertの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)指定した場合(trueの場合)、マッピング・フィールドはSQL生成中に |
false |
@ReturnUpdate
を使用して、UPDATE
操作で書込み中のオブジェクトに値を戻します。これにより、表のデフォルト値、トリガー、またはストアド・プロシージャの計算された値をオブジェクトに戻して設定できます。
注意: 戻りは、Oracle Databaseでのみサポートされ、INSERT RETURNING 句が必要です。
他のデータベースで戻りを使用する場合、出力パラメータを持つストアド・プロシージャを挿入問合せに使用します。 |
@RoundRobinPartitioning
を使用して、要求をラウンド・ロビン方式で一連の接続プールに送信します。
表2-68 @RoundRobinPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
|
|
(オプション)ロード・バランシングする接続プール名のリスト |
|
|
(オプション)これにより、一連のデータベースを書込み、同期を保持し、データベース間で読取りをロード・バランシングすることができます。 |
|
使用方法
@RoundRobinPartitioning
注釈を使用して、データベース・マシンのクラスタ間で読取り問合せをロード・バランシングします。@RoundRobinPartitioning
を使用するには、すべてのデータベースを各マシンでレプリケートする必要があります。
データを読取り専用にするか、データベースで書込みをレプリケートする必要があります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
@SerializedObject
注釈を使用して、org.eclipse.persistence.descriptors.SerializedObjectPolicy
インスタンスをEntity
オブジェクトまたはMappedSuperClass
オブジェクトに設定します。シリアライズ・オブジェクト・ポリシーが指定されている場合、エンティティ・オブジェクト全体が、私有された(およびネストされた私有の)エンティティと要素コレクションを使用してデータベースの追加フィールドに書き込まれます。
使用方法
@SerializedObject
注釈を使用して、データベースから高速にデータを読み取ります。この使用法の短所は、データベースへの書込みが遅くなる点です。読取り専用またはほとんどが読取りのアプリケーションでは、エンティティと要素コレクションにシリアライズ・オブジェクト・ポリシーを使用します。
シリアライズ・オブジェクトにnull
または廃止されたバージョンのオブジェクトが含まれる場合、シリアライズ・オブジェクト・ポリシーを使用している問合せは例外をスローするか、他のフィールドすべてが同様に読み込まれている場合は、これらのフィールドを使用してオブジェクトを構築します(シリアライズ・オブジェクト・ポリシーが使用されていない場合も同様)。
注意: 現時点で、SerializedObjectPolicy インタフェースのデフォルト実装はありません。このクラスを作成する必要があります。 |
例
例2-106に、@SerializedObject注釈を使用してシリアライズ・オブジェクト・ポリシーを指定する方法およびデフォルトの列名をオーバーライドする方法を示します。
例2-106 シリアライズ・オブジェクト・ポリシーの指定
@Entity @SerializedObject(MySerializedPolicy.class); public class Employee {... @Entity @SerializedObject(value = MySerializedObjectPolicy.class, column = @Column(name = "SERIALIZED")); public class Address (...
エンティティ・オブジェクトに@SerializedObject注釈が設定されている場合、検索やリフレッシュに加えて、そのオブジェクトを返す読取り問合せでは、デフォルトでそのシリアライズ・オブジェクト・ポリシーが使用されます。
例2-107に、問合せでシリアライズ・オブジェクト・ポリシーの使用を回避する方法を示します。
例2-107 問合せでのシリアライズ・オブジェクト・ポリシーの使用の回避
Query query = em.createQuery("SELECT e FROM Employee e") .setHint(QueryHints.SERIALIZED_OBJECT, "false");
例2-108に、シリアライズ・オブジェクト・ポリシー・プロパティを使用して、シリアライズ・オブジェクトの検索を回避する方法を示します。
NamedStoredProcedureQuery
注釈内で@StoredProcedureParameter
を使用します。
表2-70 @StoredProcedureParameterの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)問合せパラメータ名。 |
|
|
(オプション)ストアド・プロシージャ・パラメータの方向。
|
|
|
(オプション) JDBCタイプ・コード。プロシージャから戻されるタイプに依存します。 |
|
|
(オプション) JDBCタイプ名。 |
|
|
(オプション)ストアド・プロシージャ・パラメータの名前。 |
|
|
(オプション)パラメータが必須かオプションか、プロシージャでデフォルト設定されるかどうかを指定します。 |
|
|
(オプション)プロシージャから戻されるJavaクラスのタイプ。プロシージャから戻される |
|
@Structを使用して、データベースのStruct
型にマップするクラスを定義します。通常、埋込み可能クラスである必要がありますが、オブジェクト表に格納される場合はエンティティも可能です。
表2-71 @Structの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)データベース構造型のデータベース名 |
|
|
(オプション)データベース構造型に含まれるフィールドの順序を定義します。 |
使用方法
Struct
型は、一部のデータベースでサポートされる拡張オブジェクト・リレーショナル・データ型です。Struct型は、OracleのOBJECT
型など、データベースのユーザー定義型です。Structには通常、Arrays (VARRAY
)型またはその他のStruct型が含まれ、Structは列または表に格納できます。
Struct
型を使用して、Oracle DatabaseでRECORD
型を使用するPL/SQLストアド・プロシージャをコールすることもできます。
例
例2-109に、@Struct
注釈を使用してOBJECT
型にマップするJavaクラスを定義する方法を示します。
例2-109 @Struct注釈の使用
@Embeddable
@Struct(name="EMP_TYPE", fields={"F_NAME", "L_NAME", "SALARY"})
public class Employee {
@Column(name="F_NAME")
private String firstName;
@Column(name="L_NAME")
private String lastName;
@Column(name="SALARY")
private BigDecimal salary;
...
}
例2-110に、eclipselink-orm.xml
ファイルの<struct>
要素を使用する方法を示します。
例2-110 <struct> XMLの使用
<embeddable class="Address" access="FIELD"> <struct name="PLSQL_P_PLSQL_ADDRESS_REC"> <field>ADDRESS_ID</field> <field>STREET_NUM</field> <field>STREET</field> <field>CITY</field> <field>STATE</field> </struct> <attributes> <basic name="id"> <column name="ADDRESS_ID"/> </basic> <basic name="number"> <column name="STREET_NUM"/> </basic> </attributes> </embeddable>
@StructConverter
を使用して、空間データ型などの複雑なデータベース・タイプを処理するjava.sql.Struct
タイプのカスタム処理を有効にします。
EclipseLinkには、Oracle JGeometry
空間データ型を変換するJGeometryConverter
クラスが含まれています。
注意: 他のコンバータとは異なり、@StructConverter には独自のインタフェースがあります。 |
使用方法
値属性がStructConverter
名に設定されている既存の@Convert
注釈を使用できます。この場合、適切な設定がマッピングに適用されます。この設定は、StructConverter
が定義されているタイプを使用するすべてのマッピングに必要です。@Convert
を使用したマッピングの構成に失敗すると、エラーが発生します。
EclipseLinkには、@ObjectTypeConverter
や@TypeConverter
などのその他のコンバータも含まれます。
例
例2-111に、@StructConverter
注釈を定義する方法を示します。
例2-111 @StructConverter注釈の使用
@StructConverter( name="JGeometryConverter" converter=JGeometryConverter.class.getName())
すべてのセッションの範囲でエンティティに@StructConverter
注釈を指定できます。同じJavaタイプに影響する複数のStructConverter
注釈を追加すると、例外がスローされます。@StructConverter
注釈は、@Converter
と同じネームスペースにあります。@Converter
および同じ名前の@StructConverter
を追加すると、検証の例外がスローされます。
@StructConverters
を使用して、複数の@StructConverter
注釈を定義します。
例
例2-112に、@StructConverters
注釈を使用して複数の@StructConverter
要素を定義する方法を示します。
例2-112 @StructConverters注釈の使用
@StructConverters{{ @StructConverter(name="StructConverter1", converter="foo.StructConverter1"), @StructConverter(name="StructConverter2", converter="foo.StructConverter2") })
例2-113に、eclipselink-orm.xml
ファイルの<struct-converters>
要素を使用する方法を示します。
フィールド/メソッドで@Structure
を使用して、埋込み可能なStruct
型にStructureMapping
を定義します。Struct注釈を使用して、ターゲットの埋込み可能クラスをマップする必要があります。
使用方法
Struct型は、一部のデータベースでサポートされる拡張オブジェクト・リレーショナル・データ型です。Struct型は、OracleのOBJECT
型など、データベースのユーザー定義型です。Structには通常、Arrays (VARRAY
)型またはその他のStruct型が含まれ、Structは列または表に格納できます。
@TenantDiscriminator
注釈は、@Multitenant
注釈およびSINGLE-TABLE
マルチテナント・タイプとともに使用され、永続性コンテキストが単一表マルチテナンシでアクセスできる対象を制限します。
表2-74 @TenantDiscriminatorColumnのプロパティ
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)識別子列のDDLを生成する際に使用されるSQLフラグメント |
指定の識別子タイプの列を作成するプロバイダ生成SQL。 |
|
(オプション)テナント識別子列に適用されるコンテキスト・プロパティの名前 |
|
|
(オプション)クラス識別子として使用するオブジェクト/列のタイプ |
|
|
(オプション)文字列ベースの識別子タイプの列長 |
文字列ベースの識別子タイプの列長。その他の識別子タイプでは無視されます。 |
|
(オプション)テナント識別子に使用される列の名前 |
|
|
テナント識別子列が表の主キーの一部であることを指定します。 |
|
|
(オプション)列を含む表の名前 |
列を含む表の名前。存在しない場合、列はプライマリ表にあると想定されます。列がセカンダリ表にある場合は、この属性を指定する必要があります。 |
使用方法
単一表マルチテナンシを構成する場合は、次の両方を指定する必要があります。
次のとおり、@Multitenant
注釈を使用して、単一表マルチテナンシを使用するためにエンティティまたはマップされたスーパークラスに注釈を付与します。
@Entity @Table(name=”EMP”) @Multitenant(SINGLE_TABLE)
SINGLE_TABLE
は、指定されたエンティティに関連付けられている表(Table
およびSecondaryTable
)をテナント間で共有できることを示します。
注意: 識別子列はプライマリ表にあると想定されるため、@Table 注釈は必要ありません。ただし、識別子列がセカンダリ表に定義されている場合、@SecondaryTable を使用してその表を特定する必要があります。 |
次のとおり、@TenantDiscriminatorColumn
注釈を使用して、識別子列として使用される列を指定します。
@Entity @Table(name=”EMP”) @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumn(name = ”TENANT_ID”)
次のとおり、@TenantDiscriminatorColumns
注釈を使用することにより、複数の識別子列を指定できます。
@Entity @Table(name = "EMPLOYEE") @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumns({ @TenantDiscriminatorColumn(name = "TENANT_ID") @TenantDiscriminatorColumn(name = "TENANT_CODE" contextProperty="eclipselink.tenant-code")})
識別子列の使用
次の特性が、識別子列に適用されます。
永続化する場合、テナント識別子列の値は、関連付けられたコンテキスト・プロパティから移入されます。
テナント識別子列は、アプリケーションで定義できます。つまり、識別子列は、各共有エンティティ表の固有の列に関連付けられません。TENANT_ID
、T_ID
などを使用できます。
アプリケーションが定義できるテナント識別子列の数に制限はありません。
識別子列には任意の名前を使用できます。
テナント識別子列は、常に@Multitenant(SINGLE_TABLE
)とともに使用される必要があります。テナント識別子列のみを指定することはできません。
生成されたスキーマに指定のテナント識別子列を含めることができます。
テナント識別子列をマップまたはマップ解除できます。
テナント識別子列がマップされる場合、関連付けられたマッピング属性は読取り専用としてマークする必要があります。この制限により、テナント識別子列をエンティティIDの一部にすることはできず、データベースの主キー仕様の一部にすることだけが可能になります。
SELECT
問合せを発行する場合、マップされたプロパティとマップ解除されたプロパティの両方を使用して追加基準を作成します。
継承階層での単一表マルチテナンシの使用
継承方針は、継承タイプを指定することによって構成されます(@javax.persistence.Inheritanceを参照してください)。単一表マルチテナンシは、次のとおり、継承階層で使用できます。
SINGLE_TABLE
またはJOINED
継承方針を使用する場合、マルチテナント・メタデータは継承階層のルート・レベルでのみ適用できます。
TABLE_PER_CLASS
継承階層内でもマルチテナント・メタデータを指定できます。この場合、すべてのエンティティに、すべてのマッピングデータが含まれた独自の表があります(SINGLE_TABLE
またはJOINED
方針の場合はありません)。その結果、TABLE_PER_CLASS
方針では、階層の一部のエンティティがマルチテナントになり、その他はマルチテナントにならない場合があります。エンティティを単一表に分離してタイプのみを構築することはできないため、その他の継承方針ではルート・レベルでマルチテナンシのみを指定できます。
例
表2-74に、テナント識別子列の多くの使用例を示します。
例2-116 @TenantDiscriminatorColumn注釈の使用
/** Single tenant discriminator column **/ @Entity @Table(name = "CUSTOMER") @Multitenant @TenantDiscriminatorColumn(name = "TENANT", contextProperty = "multi-tenant.id") public Customer() { ... } /** Multiple tenant discriminator columns using multiple tables **/ @Entity @Table(name = "EMPLOYEE") @SecondaryTable(name = "RESPONSIBILITIES") @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumns({ @TenantDiscriminatorColumn(name = "TENANT_ID", contextProperty = "employee-tenant.id", length = 20) @TenantDiscriminatorColumn(name = "TENANT_CODE", contextProperty = "employee-tenant.code", discriminatorType = STRING, table = "RESPONSIBILITIES") } ) public Employee() { ... } /** Tenant discriminator column mapped as part of the primary key on the database **/ @Entity @Table(name = "ADDRESS") @Multitenant @TenantDiscriminatorColumn(name = "TENANT", contextProperty = "tenant.id", primaryKey = true) public Address() { ... } /** Mapped tenant discriminator column **/ @Entity @Table(name = "Player") @Multitenant @TenantDiscriminatorColumn(name = "AGE", contextProperty = "tenant.age") public Player() { ... @Basic @Column(name="AGE", insertable="false", updatable="false") public int age; }
例2-117に、eclipselink-orm.xml
ファイルの<tenant-disciminator-column>
XML要素を使用する同一マッピングを示します。
例2-117 <tenant-discriminator-column> XML注釈の使用
<!-- Single tenant discriminator column --> <entity class="model.Customer"> <multitenant> <tenant-discriminator-column name="TENANT context-property="multi-tenant.id""/> </multitenant> <table name="CUSTOMER"/> ... </entity>
<!-- Multiple tenant discriminator columns using multiple tables --> <entity class="model.Employee"> <multitenant type="SINGLE_TABLE"> <tenant-discriminator-column name="TENANT_ID" context-property="employee-tenant.id" length="20"/> <tenant-discriminator-column name="TENANT_CODE" context-property="employee-tenant.id" discriminator-type="STRING" table="RESPONSIBILITIES"/> </multitenant> <table name="EMPLOYEE"/> <secondary-table name="RESPONSIBILITIES"/> ... </entity>
<!-- Tenant discriminator column mapped as part of the primary key on the database --> <entity class="model.Address"> <multitenant> <tenant-discriminator-column name="TENANT" context-property="multi-tenant.id" primary-key="true"/> </multitenant> <table name="ADDRESS"/> ... </entity>
<!-- Mapped tenant discriminator column --> <entity class="model.Player"> <multi-tenant> <tenant-discriminator-column name="AGE" context-property="tenant.age"/> </multi-tenant> <table name="PLAYER"/> ... <attributes> <basic name="age" insertable="false" updatable="false"> <column name="AGE"/> </basic> ... </attributes> ... </entity>
複数の@TenantDiscriminatorColumn
注釈を含む@TenantDiscriminatorColumns
注釈を使用して、複数の識別子列を単一表マルチテナンシに指定します。
表2-75 @TenantDiscriminatorColumnsの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション) 1つ以上の |
なし |
使用方法
@TenantDiscriminatorColumns
注釈を使用して複数の@TenantDiscriminatorColumn
を含める必要があります。@TenantDiscriminatorColumns
注釈を単独で使用することはできず、複数の@TenantDiscriminatorColumn
注釈を@TenantDiscriminatorColumns
なしで単独で使用することはできません。
例
@Entity @Table(name = "EMPLOYEE") @Multitenant(SINGLE_TABLE) @TenantDiscriminatorColumns({ @TenantDiscriminatorColumn(name = "TENANT_ID", contextProperty = ”tenant-id) @TenantDiscriminatorColumn(name = "TENANT_CODE", contextProperty = ”tenant-code)})
@TenantDiscriminatorColumns
の詳細な例は、「@TenantDiscriminatorColumn」を参照してください。
テナントごとの表マルチテナンシにより、アプリケーションの複数のテナントは、1つ以上のテナント固有の表にデータを分離できます。テナント表識別子は、テナントごとの表マルチテナンシ方針でテナント表と他のテナント表を区別する方法を指定します。
使用方法
テナントごとの表マルチテナンシでは、テナントの表は、接頭辞または接尾辞のネーミング・パターンを使用して区別することで同じスキーマに存在できます。または、異なるスキーマに存在できます。テナント表識別子により、テナントの表を特定して他のテナントの表から分離するために、接頭辞または接尾辞のネーミング・パターンを使用するか異なるスキーマを使用するかが特定されます。タイプは次のとおりです。
スキーマ: テナント表識別子をスキーマとしてすべてのマルチテナント表に適用します。この方針には、適切なデータベース・プロビジョニングが必要です。
接尾辞: テナント表識別子を接尾辞としてすべてのマルチテナント表に適用します。これはデフォルトの方針です。
接頭辞: テナント表識別子を接頭辞としてすべてのマルチテナント表に適用します。
テナント表識別子は、エンティティ・レベルまたはマップされたスーパークラス・レベルで指定することができ、常にMultitenant(TABLE_PER_TENANT)
とともに使用される必要があります。テナント表識別子のみの指定では不十分です。
@TenantTableDiscriminator
およびテナントごとの表マルチテナンシの使用の詳細は、「@Multitenant」を参照してください。
例
次の例に、SCHEMA
タイプの表識別子を示します。
関連項目
EclipseLinkソリューション・ガイドのマルチテナンシの使用に関する項
マルチテナントの例: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant
トランスフォーメーション・マッピングとともに@Transformation
を使用して、データベース列から属性値への変換を定義します(トランスフォーメーション・マッピングが書込み専用ではない場合。書込み専用の場合、@ReadTransformer
注釈が必要です)。
表2-78 @Transformationの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)フィールドまたはプロパティの値を遅延ロードする必要があるか、または即時にフェッチする必要があるかどうかを定義します。
|
|
|
(オプション)フィールドまたはプロパティの値が |
|
使用方法
読取り専用マッピングではない場合、WriteTransformer
注釈またはWriteTransformers
注釈のいずれかを指定する必要があります。各WriteTransformer
は、属性値から単一データベース列値への変換を定義します(列はWriteTransformer
で指定されます)。
例
例2-120に、@Transformation
注釈を使用する方法を示します。
例2-120 @Transformation注釈の使用
@Transformation(fetch=FecthType.LAZY, optional="true")
@ReadTransformer(class=package.MyNormalHoursTransformer.class)
@WriteTranformers({
@WriteTranformer(column=@Column(name="START_TIME"),
method="getStartDate"),
@WriteTranformer(column=@Column(name="END_TIME"),
class=package.MyTimeTransformer.class)
})
@Mutable
@ReturnUpdate
@Access(AccessType.PROPERTY)
@AccessMethods(get="getNormalHours", set="setNormalHours")
@Properties({
@Property(name="x", value="y")
})
例2-121に、eclipselink-orm.xml
ファイルの<transformation>
XML要素を使用する同一マッピングを示します。
例2-121 <transformation> XMLの使用
<transformation name="normalHours" fetch="LAZY" optional="true"> <read-transformer method="buildNormalHours"/> <write-transformer method="getStartTime"> <column name="START_TIME"/> </write-transformer> <write-transformer class="package.MyTimeTransformer"> <column name="END_TIME"/> </write-transformer> <mutable/> <return-update/> <access type="PROPERTY"/> <access-methods get="getNormalHours" set="setNormalHours"/> <properties> <property name="x" value="y"/> </properties> </transformation>
@TypeConverter
を使用して、マップ済属性の読取りおよび書込み中にデータ値を変更します。
注釈要素
表2-79は、この注釈の要素を示しています。
表2-79 @TypeConverterの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)コンバータの |
なし |
|
(オプション)データベースに格納される |
|
|
(オプション)エンティティに格納される |
|
脚注 1 デフォルトは、永続性フィールドまたはプロパティのタイプから推測されます。
使用方法
各TypeConverter
は、一意の名前を付ける必要があり、クラス、フィールドおよびプロパティ・レベルで定義でき、エンティティ、MappedSuperclassおよび埋込み可能クラス内で指定できます。TypeConverter
は、常に@Convert
注釈を使用して指定されます。
@TypeConverter
をBasic
、BasicMap
またはBasicCollection
マッピングに配置できます。
EclipseLinkには、@ObjectTypeConverter
および@StructConverter
コンバータも含まれています。
@TypeConverters
を使用して、複数のTypeConverter
要素を定義します。
例
例2-123に、この注釈を使用する方法を示します。
例2-123 @TypeConverters注釈の使用
@Entity
@TypeConverters({
@TypeConverter(name="BigIntegerToString",dataType=String.class,objectType=BigInteger.class)
})
public class Parameters implements Serializable {
private static final long serialVersionUID = -1979843739878183696L;
@Column(name="maxValue", nullable=false, length=512)
@Convert("BigIntegerToString")
private BigInteger maxValue;
...
}
例2-123に、eclipselink-orm.xml
ファイルの<type-converters>
要素を使用する方法を示します。
@UnionPartitioning
を使用して、問合せをすべての接続プールに送信し、結果を統合します。これは、パーティション・リレーションシップ間のManyToManyなど、パーティション化を使用する際にパーティションに及ぶ問合せまたはリレーションシップに使用できます。
表2-81 @UnionPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
|
|
ロード・バランシングする接続プール名のリスト。 |
デフォルトで |
|
書込み問合せをレプリケートするかどうかを定義します。 統合時に書込みは通常レプリケートされませんが、結合表をレプリケートする必要がある場合は、ManyToManyリレーションシップのために統合できます。 |
|
使用方法
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットでパーティション化を有効にできます。パーティション・ポリシーは、再利用できるようにグローバルに名付けられ、@Partitioned
注釈を使用して設定される必要もあります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
@UuidGenerator
を使用して、ジェネレータ要素が@GeneratedValue
注釈に指定される際に名前で参照できる主キー・ジェネレータを定義します。UUID (全体の一意識別子)ジェネレータは、エンティティ・クラスまたは主キー・フィールドかプロパティに指定される場合があります。
ジェネレータ名は、永続性ユニットに対して(つまり、すべてのジェネレータ・タイプ間で)グローバルです。
例
例2-125に、この注釈を使用する方法を示します。
例2-125 @UuidGenerator注釈の使用
@Entity
@UuidGenerator(name="EMP_ID_GEN")
public class Employee {
@Id
@GeneratedValue(generator="EMP_ID_GEN")
private String id;
}
例2-126に示すとおり、eclipselink-orm.xml
ファイルでSessionCustomizer
を指定して名前付きシーケンスを構成することもできます。
例2-126 <generated-value> XMLの使用
<id name="id">
<column name="PROJ_ID" />
<generated-value generator="system-uuid"/>
</id>
例2-127に示すとおり、永続性ユニット・レベル(persistence.xml
ファイル)で名前付きシーケンスを指定することもできます。
@UnionPartitioning
を使用して、問合せをすべての接続プールに送信し、結果を統合します。これは、パーティション・リレーションシップ間のManyToManyなど、パーティション化を使用する際にパーティションに及ぶ問合せまたはリレーションシップに使用できます。
表2-83 @UnionPartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
|
|
ロード・バランシングする接続プール名のリスト。 |
デフォルトで |
|
書込み問合せをレプリケートするかどうかを定義します。 統合時に書込みは通常レプリケートされませんが、結合表をレプリケートする必要がある場合は、ManyToManyリレーションシップのために統合できます。 |
|
使用方法
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットでパーティション化を有効にできます。パーティション・ポリシーは、再利用できるようにグローバルに名付けられ、@Partitioned
注釈を使用して設定される必要もあります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
@ValuePartition
を使用して、特定の接続プールにルーティングされる特定の値パーティションを表現します。
例
例2-128に、@ValuePartition
および@ValuePartitioning
注釈を使用する方法を示します。
例2-128 @ValuePartition注釈の使用
@Entity @Table(name = "PART_EMPLOYEE") @IdClass(EmployeePK.class) @ValuePartitioning( name="ValuePartitioningByLOCATION", partitionColumn=@Column(name="LOCATION"), unionUnpartitionableQueries=true, defaultConnectionPool="default", partitions={ @ValuePartition(connectionPool="node2", value="Ottawa"), @ValuePartition(connectionPool="node3", value="Toronto") }) @Partitioned("ValuePartitioningByLOCATION") public class Employee implements Serializable, Cloneable { ... }
例2-129に、eclipselink-orm.xml
ファイルの<partition>
要素を使用する方法を示します。
例2-129 <partition> XMLの使用
<entity name="Employee" class="Employee" access="FIELD">
<table name="PART_EMPLOYEE"/>
<id-class class="EmployeePK"/>
<value-partitioning name="ValuePartitioningByLOCATION" union-unpartitionable-queries="true" default-connection-pool="default">
<partition-column name="LOCATION"/>
<partition connection-pool="node2" value="Ottawa"/>
<partition connection-pool="node3" value="Toronto"/>
</value-partitioning>
<partitioned>ValuePartitioningByLOCATION</partitioned>
@ValuePartitioning
を使用して、オブジェクト(オブジェクトの場所、テナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。各値は、特定のサーバーに割り当てられます。その値を持つオブジェクトに対するすべての書込みまたは読取り要求は、サーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
表2-85 @ValuePartitioningの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(必須)パーティション・ポリシーの名前。名前は、永続性ユニットに一意である必要があります。 |
|
|
(必須)問合せをパーティション化するためのデータベース列または問合せパラメータ。 これは表列名であり、クラス属性名ではありません。列値は、問合せに含まれている必要があり、通常はオブジェクトIDの一部です。これは、問合せパラメータの名前にもなります。 問合せにフィールドが含まれていない場合、問合せはパーティション化されません。 |
|
|
(必須)値パーティションを格納します。各パーティションは、値を |
|
|
(オプション)デフォルトの接続プールは、マップされていない値に使用されます。 |
|
|
(オプション)開始値および終了値の |
|
|
(オプション)パーティション・フィールドを含まない問合せをすべてのデータベースに送信し、結果を統合するかどうかを定義します。 |
|
使用方法
エンティティ、リレーションシップ、問合せまたはセッション/永続性ユニットでパーティション化を有効にできます。パーティション・ポリシーは、再利用できるようにグローバルに名付けられ、@Partitioned
注釈を使用して設定される必要もあります。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの適切な2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
@VariableOneToOne
を使用して、Javaオブジェクトとインタフェースの実装者の間のポインタ参照を表します。このマッピングは、通常、ソース・オブジェクトとターゲット・オブジェクトの間の1つのポインタ(インスタンス変数に格納されます)で表されます。リレーショナル・データベース表では、これらのマッピングは通常、外部キーとタイプ・コードを使用して実装されます。
表2-86 @VariableOneToOneの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)アソシエーションのターゲットにカスケードされる必要がある操作の配列 |
|
|
(オプション)このマッピングとともに使用できる識別子タイプの配列 |
何も指定されていない場合、EclipseLinkは、ターゲット・インタフェースを実装する永続性ユニット内のエンティティを追加します。
|
|
(オプション)タイプ識別子を含む識別子列 |
|
|
(オプション)フィールドまたはプロパティの値をロードする方法を指定します。
|
|
|
(オプション)アソシエーションがオプションかどうかを指定します。 |
|
|
(オプション)インタフェース・クラスがこのマッピングのターゲットであるかどうかを示します。 |
|
|
(オプション)このマッピングのターゲットであるインタフェース・クラス |
何も指定されていない場合、EclipseLinkは、参照されるオブジェクトのタイプに基づいてインタフェース・クラスを推測します。 |
例
例2-130に、@VariableOneToOne
注釈を使用する方法を示します。
例2-130 @VariableOneToOne注釈の使用
@VariableOneToOne(
cascade={ALL},
fetch=LAZY,
discriminatorColumn=@DiscriminatorColumn(name="CONTACT_TYPE"),
discriminatorClasses={
@DiscriminatorClass(discriminator="E", value="Email.class"),
@DiscriminatorClass(discriminator="P", value="Phone.class")
}
}
@JoinColumn(name="CONTACT_ID", referencedColumnName="C_ID")
@PrivateOwned
@JoinFetch(INNER)
public Contact getContact() {
return contact;
}
例2-131に、eclipselink-orm.xml
ファイルの<variable-one-to-one>
XML要素を使用する同一マッピングを示します。
例2-131 <variable-one-to-one> XMLの使用
<variable-one-to-one name="contact" fetch="LAZY"> <cascade> <cascade-all/> </cascade> <discriminator-column name="CONTACT_TYPE"/> <discriminator-class discriminator="E" value="Email.class"/> <discriminator-class discriminator="P" value="Phone.class"/> <join-column name="CONTACT_ID" referenced-column-name="C_ID"/> <private-owned/> <join-fetch>INNER</join-fetch> </variable-one-to-one>
@VirtualAccessMethods
を使用して、特定のクラスに仮想メソッドが含まれることを指定します。
表2-87 @VirtualAccessMethodsの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)仮想プロパティに使用する
|
|
set |
(オプション)仮想プロパティに使用する
|
|
例
表2-87に、プロパティ・アクセスを使用するエンティティを示します。
例2-132 @VirtualAccessMethods注釈の使用
@Entity
@VirtualAccessMethods
public class Customer{
@Id
private int id;
...
@Transient
private Map<String, Object> extensions;
public <T> T get(String name) {
return (T) extensions.get(name);
}
public Object set(String name, Object value) {
return extensions.put(name, value);
}
@VirtualAccessMethods
注釈の使用に加えて、例2-133に示すとおり、eclipselink-orm.xml
ファイルの<access>
および<access-method>
要素も使用できます。
TranformationMapping
で@WriteTransformer
を使用して、単一の属性値を単一のデータベース列値に変換します。@WriteTransformers
注釈を使用して、複数の変換をラップします。
表2-88 @WriteTransformerの注釈要素
注釈要素 | 説明 | デフォルト |
---|---|---|
|
(オプション)値を書き込む必要がある列 単一の |
|
|
(オプション) マップされたクラスに必要な 注意: DDL生成とリターン・ポリシーをサポートする場合、 デフォルトで |
|
|
(オプション) 注意: DDL生成とリターン・ポリシーをサポートする場合、インタフェースで定義されたように |
|
注意: transformerClass またはmethod のいずれか(両方ではない)を指定する必要があります。 |
使用方法
読取り専用マッピングに@WriteTransformer
を定義することはできません。
TransformationMapping
が書込み専用ではない場合、データベース列値から属性値への変換を定義するReadTransformer
が含まれる必要があります。
フィールドとトランスフォーマの関連付けの構成
FieldTransformer
の使用は非介入的です。ドメイン・オブジェクトは、EclipseLinkインタフェースを実装したり特別な変換メソッドを提供する必要はありません。
メソッド・ベース・フィールド・トランスフォーマは、AbstractTransformationMapping
メソッドaddFieldTransformation
を使用し、使用するデータベース・フィールド名とドメイン・オブジェクト・メソッドの名前を渡すことで構成できます。
クラス・ベース・フィールド・トランスフォーマは、AbstractTransformationMapping
メソッドaddFieldTransformer
を使用し、データベース・フィールド名およびorg.eclipse.persistence.mappings.Transfomers.FieldTransformer
のインスタンスを渡すことで構成できます。
FieldTransformer
を作成するには、FieldTransformerAdapter
を拡張すると便利です。