72
Red Hat JBoss Web Server 1.0 Hibernate Annotations リファレンスガイド for Use with Red Hat JBoss Web Server エディッション 1.0.2 Last Updated: 2017-11-13

Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Embed Size (px)

Citation preview

Page 1: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Red Hat JBoss Web Server 1.0

Hibernate Annotations リファレンスガイド

for Use with Red Hat JBoss Web Serverエディッション 1.0.2

Last Updated: 2017-11-13

Page 2: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト
Page 3: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Red Hat JBoss Web Server 1.0 Hibernate Annotations リファレンスガイド

for Use with Red Hat JBoss Web Serverエディッション 1.0.2

Red Hat ドキュメンテーショングループ

Page 4: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

法律上の通知法律上の通知

Copyright © 2011 Red Hat, Inc.

This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0Unported License. If you distribute this document, or a modified version of it, you must provideattribution to Red Hat, Inc. and provide a link to the original. If the document is modified, all Red Hattrademarks must be removed.

Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert,Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.

Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinitylogo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and othercountries.

Linux ® is the registered trademark of Linus Torvalds in the United States and other countries.

Java ® is a registered trademark of Oracle and/or its affiliates.

XFS ® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United Statesand/or other countries.

MySQL ® is a registered trademark of MySQL AB in the United States, the European Union andother countries.

Node.js ® is an official trademark of Joyent. Red Hat Software Collections is not formally related toor endorsed by the official Joyent Node.js open source or commercial project.

The OpenStack ® Word Mark and OpenStack logo are either registered trademarks/service marksor trademarks/service marks of the OpenStack Foundation, in the United States and other countriesand are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed orsponsored by the OpenStack Foundation, or the OpenStack community.

All other trademarks are the property of their respective owners.

概要概要

The Hibernate Annotations Reference Guide for Red Hat JBoss Web Server.

Page 5: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

目次目次

第第1章章 はじめにはじめに

第第2章章 アノテーションプロジェクトの設定アノテーションプロジェクトの設定2.1. 要件2.2. 設定2.3. ロギング

第第3章章 エンティティエンティティ BEAN3.1. 概要3.2. JPA アノテーションとのマッピング

3.2.1. エンティティ Bean の宣言3.2.1.1. テーブルの定義3.2.1.2. オプティミスティックロッキングのバージョン機能

3.2.2. 単純なプロパティのマッピング3.2.2.1. 基本的なプロパティマッピングの宣言3.2.2.2. カラム属性の宣言3.2.2.3. 組み込みオブジェクト (コンポーネントとも呼ばれます)3.2.2.4. アノテートされていないプロパティデフォルト値

3.2.3. ID プロパティのマッピング3.2.4. 継承のマッピング

3.2.4.1. クラスごとのテーブル3.2.4.2. クラス階層ごとの単一テーブル3.2.4.3. 結合サブクラス3.2.4.4. スーパークラスからのプロパティの継承

3.2.5. エンティティ Bean 関係のマッピング3.2.5.1. 1 対 13.2.5.2. 多対 13.2.5.3. コレクション

3.2.5.3.1. 概要3.2.5.3.2. 1 対多3.2.5.3.3. 多対多

3.2.5.4. カスケード機能を持つトランシティブ永続化3.2.5.5. 関係フェッチング

3.2.6. 複合プライマリおよび外部キーのマッピング3.2.7. セカンダリテーブルのマッピング

3.3. クエリのマッピング3.3.Mapping JPAQL/HQL queries. JPAQL/HQL クエリのマッピング3.3.2. ネイティブクエリのマッピング

3.4. HIBERNATE ANNOTATION 拡張機能3.4.1. エンティティ3.4.Identifier. Identifier

3.4.Identifier.1. ジェネレータ3.4.Identifier.2. @NaturalId

3.4.3. プロパティ3.4.3.1. アクセスタイプ3.4.3.2. 式3.4.3.3. タイプ3.4.3.4. インデックス3.4.3.5. @Parent3.4.3.6. 生成されたプロパティ3.4.3.7. @Target3.4.3.8. オプティミスティックロック

4

5556

88889999

11121414181818191921212324242628303131323333353839414141424244444545464646

目次目次

1

Page 6: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.4.4. 継承3.4.5. 単一の関係関連のアノテーション

3.4.5.1. レイジーオプションとフェッチモード3.4.5.2. @Any

3.4.6. コレクション関連アノテーション3.4.6.1. コレクション設定の拡張3.4.6.2. 追加のコレクションタイプ

3.4.6.2.1. リスト3.4.6.2.2. Map3.4.6.2.3. インデックス化されたコレクションを持つ双方向の関係3.4.6.2.4. プライマリキー付きのバッグ3.4.6.2.5. エレメントまたは複合エレメントのコレクション3.4.6.2.6. @ManyToAny

3.4.7. カスケード3.4.8. キャッシュ3.4.9. フィルター3.4.10. クエリ3.4.11. CRUD 操作に対するカスタム SQL3.4.12. Tuplizer

第第4章章 XML を使用したメタデータのオーバーライドを使用したメタデータのオーバーライド4.1. 原則

4.1.1. グローバルレベルメタデータ4.1.2. エンティティレベルメタデータ4.1.3. プロパティレベルメタデータ4.1.4. 関係レベルメタデータ

付録付録A 改訂履歴改訂履歴

46474849505051515152535355565657585860

626262626667

68

Hibernate Annotations リファレンスガイドリファレンスガイド

2

Page 7: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

目次目次

3

Page 8: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

第1章 はじめに他のすべてのオブジェクト/関係マッピングツールと同様に、Hibernate は 1 つの形式から別の形式へのデータの変換を担当するメタデータを必要とします。Hibernate 2.x では、メタデータのマッピングは通常 XML テキストファイルで宣言されます。または、XDoclet を使用して Javadoc ソースコードアノテーションをコンパイル時プリプロセッサとともに使用することができます。

同様のアノテーションサポートが標準 JDK で利用できるようになりました (ただし、より強力であり、ツールサポートがより優れています)。たとえば、IntelliJ IDEA と Eclipse は自動コンプリート機能とJDK 5.0 アノテーションの構文ハイライト (バイトコードにコンパイルされ、実行時にリフレクションを使用して読み取られます) をサポートします。外部 XML ファイルは必要ありません。

JPA 仕様では、透過的なオブジェクト/リレーショナルマッピングパラダイムの興味と成功が認識されています。JPA 仕様では、オブジェクト/リレーショナル永続化メカニズムに必要な基本的な API とメタデータが標準化されます。Hibernate EntityManager は、JPA 永続化仕様で定義されたプログラミングインターフェイスとライフサイクルルールを実装し、Hibernate Annotations とともに信頼性のあるHibernate コア上に完全な (およびスタンドアロンの) JPA 永続化ソリューションを提供します。プロジェクトのビジネス上および技術的なニーズに応じて、3 つすべての組み合わせ、JPA プログラミングインターフェイスおよびライフサイクルなしのアノテーション、または純粋なネイティブ Hibernate を使用できます。常に、Hibernate ネイティブ API、または必要な場合はネイティブ JDBC および SQL を使用できます。

Hibernate Annotations リファレンスガイドリファレンスガイド

4

Page 9: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

第2章 アノテーションプロジェクトの設定

2.1. 要件

このリリースには Hibernate Core 3.3 以上が必要です。

このリリースは Hibernate Core 3.3.2.GA で動作することがわかっています。

JDK 5.0 以上がインストールされていることを確認します。XDoclet を引き続き使用して古いJDK バージョンでアノテーションベースのメタデータのいくつかの利点を受けることができます。このドキュメントでは、JDK 5.0 のアノテーションだけを説明しています。詳細については、XDoclet ドキュメンテーションを参照してください。

2.2. 設定

最初にクラスパスを設定します (お好きな IDE で新しいプロジェクトを作成した後)。

すべての Hibernate3 コアと必要なサードパーティライブラリをコピーします (Hibernate のlib/README.txt を参照)。

hibernate-annotations.jar、lib/hibernate-comons-annotations.jar、および lib/ejb3-persistence.jar を Hibernate Annotations ディストリビューションからクラスパスにコピーします。

また、HibernateUtil という名前の、Hibernate を静的な初期化子ブロックで起動する小さなラッパークラスを使用することが推奨されます。Hibernate ドキュメンテーションの他の場所でさまざまな形式のこのクラスを見たことがあるかもしれません。アノテーションサポートについては、このヘルパークラスを次のように拡張する必要があります:

package hello;

import org.hibernate.*;import org.hibernate.cfg.*;import test.*;import test.animals.Dog;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static { try {

sessionFactory = new AnnotationConfiguration() configure().buildSessionFactory(); } catch (Throwable ex) { // Log exception! throw new ExceptionInInitializerError(ex); } }

public static Session getSession() throws HibernateException {

第第2章章 アノテーションプロジェクトの設定アノテーションプロジェクトの設定

5

Page 10: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

ここで興味深いことは AnnotationConfiguration の使用です。パッケージとアノテートされたクラスが通常の XML 設定ファイル (通常は、hibernate.cfg.xml) で宣言されます。以下は上記の宣言と同じです。

hbm.xml と新しいアノテーションを同時に使用できることに注意してください。リソースエレメントはhbm ファイルまたは EJB3 XML デプロイメント記述子のいずれかになります。この違いは設定プロセスが透過的であるかどうかです。

または、プログラミング API を使用してアノテートされたクラスとパッケージを定義できます。

また、独自の設定メカニズムを持つ Hibernate EntityManager を使用することもできます。詳細については、このプロジェクトドキュメンテーションを参照してください。

Hibernate API でアノテーションを使用するにあたって、この起動ルーチンの変更や設定ファイル以外に違いはありません。他のプロパティ (hibernate.properties、hibernate.cfg.xml、プログラミング API など) に対してお好きな設定方法を使用できます。アノテートされた永続化クラスと従来の hbm.cfg.xml 宣言を同じ SessionFactory とともに使用することもできます。ただし、クラスは複数回宣言できません (アノテートされているか hbm.xml を使用するかどうか)。マップされたエンティティ階層で設定方針を混在させることはできません (hbm とアノテーション)。

hbm ファイルからアノテートへの移行プロセスを簡単にするために、設定メカニズムはアノテーションと hbm ファイル間のマッピングの重複を検出します。HBM ファイルは、クラスごとにアノテートされたメタデータよりも優先されます。優先度は hibernate.mapping.precedence プロパティを使用して変更できます。デフォルト値は hbm, class であり、デフォルト値を class, hbm に変更すると、重複が発生したときにアノテートされたクラスが hbm ファイルよりも優先されます。

2.3. ロギング

Hibernate Annotations はさまざまなシステムイベントをログに記録するために Simple Logging Facadefor Java (SLF4J) を使用します。SLF4J は、選択されたバインディングに応じてロギング出力を複数の

return sessionFactory.openSession(); }}

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration> <session-factory> <mapping package="test.animals"/> <mapping class="test.Flight"/> <mapping class="test.Sky"/> <mapping class="test.Person"/> <mapping class="test.animals.Dog"/> <mapping resource="test/animals/orm.xml"/> </session-factory> </hibernate-configuration>

sessionFactory = new AnnotationConfiguration() .addPackage("test.animals") //the fully qualified package name .addAnnotatedClass(Flight.class) .addAnnotatedClass(Sky.class) .addAnnotatedClass(Person.class) .addAnnotatedClass(Dog.class).addResource("test/animals/orm.xml") configure()..buildSessionFactory();

Hibernate Annotations リファレンスガイドリファレンスガイド

6

Page 11: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

ロギングフレームワーク (NOP、Simple、log4j バージョン 1.2、JDK 1.4 ロギング、JCL、またはログバック) に出力するよう指定します。ロギングを適切に設定するためには、クラスパスにslf4j-api.jar を指定し、優先するバインディングとして jar ファイルを指定する必要があります (Log4 の場合は slf4j-log4j12.jar)。詳細については、SLF4J ドキュメンテーションを参照してください。

Hibernate Annotations で興味深いロギングカテゴリは以下のとおりです。

表表2.1 Hibernate Annotations ログカテゴリログカテゴリ

カテゴリカテゴリ 機能機能

org.hibernate.cfg すべての設定関連のイベントをログに記録します (アノテーションだけではない)。

カテゴリ設定の詳細については、Hibernate Core ドキュメンテーションの ロギングを参照してください。

第第2章章 アノテーションプロジェクトの設定アノテーションプロジェクトの設定

7

Page 12: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

第3章 エンティティ BEAN

3.1. 概要

この節では、EJB 3.0 (Java Persistence とも呼ばれます) エンティティアノテーションと Hibernate 固有の拡張機能について説明します。

3.2. JPA アノテーションとのマッピング

EJB3 エンティティはプレーンな POJO です。実際には EJB3 エンティティの概念は Hibernate 永続エンティティの概念とまったく同じです。マッピングは JDK 5.0 アノテーションを使用して定義されます(オーバーライド用の XML 記述子の構文は EJB3 仕様で定義されます)。アノテーションは、論理マッピングアノテーション (オブジェクトモデルやクラスの関連付けなどの定義を可能にします) と物理マッピングアノテーション (物理スキーマ、テーブル、カラム、インデックスなどを定義します) の 2 つのカテゴリに分けることができます。以下のサンプルコードで両方のカテゴリのアノテーションを組み合わせます。

EJB3 アノテーションは javax.persistence.* パッケージに含まれます。ほとんどの JDK 5 準拠IDE (Eclipse、IntelliJ IDEA、Netbeans など) では、アノテーションインターフェースと属性をユーザーのために自動的に補完します (EJB3 アノテーションがプレーンな JDK 5 アノテーションであるため、固有の "EJB3" モジュールがない場合であっても)。

具体的かつ実践的な例については、JBoss EJB 3.0 チュートリアルを参照するか、HibernateAnnotations テストスイートを確認してください。ほとんどのユニットテストは、具体的な例を示し、さまざまなアイデアを提供するよう設計されています。

3.2.1. エンティティ Bean の宣言

バインドされた各永続 POJO クラスはエンティティ Bean であり、@Entity アノテーション (クラスレベル) を使用して宣言されています。

@Entity は、クラスをエンティティ Bean (永続 POJO クラスなど) として宣言し、@Id はこのエンティティ Bean の ID プロパティを宣言します。他のマッピング宣言は暗黙的です。例外概念に よるこの設定は新しい EJB3 仕様の中心部となるもので、主要な改善となっています。クラス Flight は Flightテーブルにマップされており、カラム id をそのプライマリキーカラムとして 使用します。

フィールドまたはメソッドをアノテートするかどうかに応じて、Hibernate で使用されるアクセスタイプは field または property になります。EJB3 仕様では、アクセスするエレメントタイプ (たとえば、property アクセスを使用する場合は getter メソッド、field アクセスを使用する場合はフィールド) に対してアノテーションを宣言する必要があります。フィールドとメソッドの両方で EJB3 アノテーションを使用することは避けてください。Hibernate は、@Id または @EmbeddedId の位置からアクセスタイプを推測します。

@Entitypublic class Flight implements Serializable { Long id;

@Id public Long getId() { return id; }

public void setId(Long id) { this.id = id; }}

Hibernate Annotations リファレンスガイドリファレンスガイド

8

Page 13: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.2.1.1. テーブルの定義

@Table はクラスレベルで設定されます。@Table を使用すると、エンティティ Bean マッピングのテーブル、カタログ、およびスキーマ名を定義できます。@Table が定義されていない場合は、デフォルト値 (エンティティの非完全クラス名) が使用されます。

@Table エレメントには、schema 属性と catalog 属性も含まれます (これらの属性を定義する必要がある場合)。また、@Table (単一のカラムにバインドされた一意の制約用、@Column を参照) とともに @UniqueConstraint アノテーションを使用することにより、テーブルに対して一意の制約を定義することもできます。

一意の制約は組の月、日に適用されます。columnNames アレイは論理カラム名を参照することに注意してください。

3.2.1.2. オプティミスティックロッキングのバージョン機能

@Version アノテーションを使用してエンティティ Bean にオプティミスティックロッキング機能を追加できます。

バージョンプロパティは OPTLOCK カラムにマップされ、エンティティマネージャはバージョンプロパティを使用して競合するアップデートを検出します ( 最後のコミットを優先 (last-commit-wins) 方針で発生する可能性があるアップデートの損失を回避します)。

バージョンカラムは数値 (推奨するソリューション) または EJB3 仕様ごとのタイムスタンプになります。適切な UserVersionType を定義および実装した場合、Hibernate はすべての種類をサポートします。

アプリケーションは Hibernate で設定されたバージョン番号を絶対に変更すべきではありません。バージョン番号を人為的に増やす場合は、Hibernate Entity Manager のリファレンスドキュメンテーションである LockMode.WRITE を参照してください。

3.2.2. 単純なプロパティのマッピング

3.2.2.1. 基本的なプロパティマッピングの宣言

エンティティ Bean の静的かつ一時的でない各プロパティ (フィールドまたはメソッド)

@Entity@Table(name="tbl_sky")public class Sky implements Serializable {...

@Table(name="tbl_sky", uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})})

@Entitypublic class Flight implements Serializable {... @Version @Column(name="OPTLOCK") public Integer getVersion() { ... }}

第第3章章 エンティティエンティティ BEAN

9

Page 14: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

は、@Transient としてアノテートしない限り、永続的と見なされます。プロパティにアノテーションを設定しない場合は、適切な @Basic アノテーションが使用されます。@Basic アノテーションを使用すると、プロパティのフェッチ方針を宣言できます。

counter (一時フィールド) と lengthInMeter (@Transient としてアノテートされたメソッド) は、エンティティマネージャによって無視されます。name プロパティ、length プロパティ、および firstname プロパティは永続としてマップされ、積極的にフェッチされます (単純なプロパティのデフォルト)。detailedComment プロパティ値は、エンティティのレイジープロパティが最初にアクセスされると、データベースから消極的にフェッチされます。通常は、単純なプロパティをレイジーにする必要はありません (レイジーアソシエーションフェッチと混同しないでください)。

注記

プロパティレベルのレイジーフェッチを有効にする場合は、クラスを実装する必要があります。このような機能を有効にするために、元のクラスにバイトコードが追加されます。Hibernate リファレンスドキュメンテーションを参照してください。クラスが実装されない場合は、プロパティレベルのレイジーローディングが暗黙的に無視されます。

推奨される別の方法は、EJB-QL または基準クエリの予測機能を使用することです。

EJB3 は、Hibernate によってサポートされたすべての基本タイプ (すべての基本的な Java タイプ、その対応するラッパー、およびシリアライズ可能なクラス) のプロパティマッピングをサポートします。Hibernate Annotations は、序数のカラム (Enum の序数の保存) または文字列ベースのカラム (Enum 文字列表現の保存) のいずれかに対するデフォルトの Enum タイプマッピングをサポートします。永続化表現 (デフォルトで序数に設定されます) は、note プロパティ例で示された @Enumerated アノテーションを使用して上書きできます。

中核的な Java API で、時間の正確性は定義されません。時間データを扱う場合は、データベースで期待された正確性を定義できます。時間データは DATE、TIME、または TIMESTAMP の正確性 (つまり、実際の日付、時間のみ、またはその両方) を持つことができます。@Temporal アノテーションを使用して微調整します。

@Lob は、プロパティタイプに応じてプロパティを Blob または Clob に永続化することを指定します。

public transient int counter; //transient property

private String firstname; //persistent property

@TransientString getLengthInMeter() { ... } //transient property

String getName() {... } // persistent property

@Basicint getLength() { ... } // persistent property

@Basic(fetch = FetchType.LAZY)String getDetailedComment() { ... } // persistent property

@Temporal(TemporalType.TIME)java.util.Date getDepartureTime() { ... } // persistent property

@Enumerated(EnumType.STRING)Starred getNote() { ... } //enum persisted as String in database

Hibernate Annotations リファレンスガイドリファレンスガイド

10

Page 15: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Clob では、java.sql.Clob、Character[]、char[]、および java.lang.String が永続化されます。Blob では、java.sql.Blob、Byte[]、byte[] 、およびシリアライズ可能なタイプが永続化されます。.

プロパティタイプが java.io.Serializable を実装し、基本的なタイプでない場合や、プロパティが @Lob でアノテートされない場合は、Hibernate の serializable タイプが使用されます。

3.2.2.2. カラム属性の宣言

プロパティマッピングに使用されるカラムは、@Column アノテーションを使用して定義できます。このアノテーションを使用してデフォルト値を上書きします (デフォルト値に関する詳細については、EJB3 仕様を参照)。このアノテーションは、以下のプロパティに対してプロパティレベルで使用できます。

まったくアノテートされていないプロパティ

@Basic でアノテートされたプロパティ

@Version でアノテートされたプロパティ

@Lob でアノテートされたプロパティ

@Temporal でアノテートされたプロパティ

@org.hibernate.annotations.CollectionOfElements でアノテートされたプロパティ(Hibernate の場合のみ)

name プロパティは、 null 非許容型で 長さが 50 の、更新できない (プロパティが変更不可になる) flight_name カラムにマップされます。

このアノテーションは、通常のプロパティと@Id プロパティまたは @Version プロパティに適用できます。

@Lobpublic String getFullText() { return fullText;}

@Lob public byte[] getFullCode() { return fullCode;}

@Entitypublic class Flight implements Serializable {...@Column(updatable = false, name = "flight_name", nullable = false, length=50)public String getName() { ... }

@Column(

name="columnName";

第第3章章 エンティティエンティティ BEAN

11

Page 16: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

name (オプション): カラム名 (デフォルトでプロパティ名に設定される)

unique (オプション): このカラムに一意の制約を設定するかどうかを設定 (デフォルト値は偽)

nullable (オプション): カラムを null 許容型として設定 (デフォルト値は真)

insertable (オプション): カラムが挿入ステートメントの一部であるかどうかを設定 (デフォルト値は真)

updatable (オプション): カラムが更新ステートメントの一部であるかどうかを設定 (デフォルト値は真)

columnDefinition (オプション): この特定のカラムの sql DDL 断片を上書き (移植不可)

table (オプション): 対象テーブルを定義 (デフォルト値はプライマリテーブル)

length (オプション): カラム長 (デフォルト値は 255)

precision (オプション): カラムの小数点以下の精度 (デフォルト値は 0)

scale (オプション): 有用なカラムの10 進型のスケール (デフォルト値は 0)

3.2.2.3. 組み込みオブジェクト (コンポーネントとも呼ばれます)

エンティティ内部に組み込みコンポーネントを宣言したり、カラムマッピングを上書きしたりできます。コンポーネントクラスは、@Embeddable アノテーションを使用してクラスレベルでアノテートす

boolean unique() default false;

boolean nullable() default true;

boolean insertable() default true;

boolean updatable() default true;

String columnDefinition() default "";

String table() default "";

int length() default 255;

int precision() default 0; // decimal precision int scale() default 0; // decimal scale

Hibernate Annotations リファレンスガイドリファレンスガイド

12

Page 17: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

る必要があります。関連するプロパティの @Embedded および @AttributeOverrideアノテーションを使用して特定のエンティティに対する組み込みオブジェクトのカラムマッピングを上書きできます。

組み込みオブジェクトは、独自のエンティティのアクセスタイプを継承します。このアクセスタイプは、Hibernate 固有の @AccessType アノテーションを使用して上書きできることに注意してください(「Hibernate Annotation 拡張機能」 を参照)。

Person エンティティ Bean は、 homeAddress と bornIn の 2 つのコンポーネントプロパティを持ちます。homeAddress プロパティはアノテートされませんでしたが、Hibernate は Address クラスの @Embeddable アノテーションを検索してそのプロパティが永続コンポーネントであることを推測します。また、カラム名のマッピング (bornCountryName に対する) を Country のマップされた各属性に対する @Embedded アノテーションと @AttributeOverride アノテーションで上書きします。示されたように、Country も Hibernate および EJB3 のデフォルトでの自動検出を使用した Address のネストされたコンポーネントです。EJB3 仕様では組み込みオブジェクトのカラムの上書きは現在サポートされていませんが、Hibernate Annotations ではドット付きの式を使用してサポートされます。

@Entitypublic class Person implements Serializable {

// Persistent component using defaults Address homeAddress;

@Embedded @AttributeOverrides( { @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ), @AttributeOverride(name="name", column = @Column(name="bornCountryName") ) } ) Country bornIn; ...}

@Embeddablepublic class Address implements Serializable { String city; Country nationality; //no overriding here}

@Embeddablepublic class Country implements Serializable { private String iso2; @Column(name="countryName") private String name;

public String getIso2() { return iso2; } public void setIso2(String iso2) { this.iso2 = iso2; }

public String getName() { return name; } public void setName(String name) { this.name = name; } ...}

@Embedded

第第3章章 エンティティエンティティ BEAN

13

Page 18: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Hibernate Annotationsは、EJB 仕様で明示的に対応されていない機能をもう一つサポートしています。@MappedSuperclassアノテーションのある組込みオブジェクトをアノテートし、スーパークラスプロパティーを永続化することができます(詳細は@MappedSuperclassを参照してください)。

EJB3 仕様によりサポートされませんが、Hibernate Annotations では組み込みオブジェクトの関連付けアノテーション (@*ToOne や @*ToMany など) を使用できます。関連付けカラムを上書きするために、@AssociationOverride を使用できます。

同じエンティティで同じ組み込み可能なオブジェクトタイプを 2 回使用する場合は、カラム名のデフォルト設定は機能しません。少なくとも 1 つのカラムが明示的である必要があります。Hibernate はEJB3 仕様の範囲を超え、NamingStrategy を使用してデフォルト設定メカニズムを拡張できます。DefaultComponentSafeNamingStrategy は、同じエンティティで使用された場合であっても組み込みオブジェクトをデフォルト設定できるデフォルトの EJB3NamingStrategy を少し改良したものです。

3.2.2.4. アノテートされていないプロパティデフォルト値

プロパティがアノテートされていない場合は、以下のルールが適用されます。

プロパティが単一タイプの場合、プロパティは @Basic とマップされます。

それ以外の場合は、プロパティタイプが @Embeddable とアノテートされているときは@Embedded とマップされます。

それ以外の場合は、プロパティのタイプがシリアル化可能であるとき、シリアル化されたバージョンのオブジェクトを保持するカラムの @Basic としてマップされます。

それ以外の場合は、プロパティのタイプが java.sql.Clob or java.sql.Blob のとき、適切なLobType で @Lob としてマップされます。

3.2.3. ID プロパティのマッピング

@Id アノテーションを使用すると、エンティティ Bean の ID となるプロパティを定義できます。このプロパティは、アプリケーション自体によって設定したり、Hibernate (推奨される方法) によって生成したりできます。@GeneratedValue アノテーションにより ID 生成方針を定義できるようになります。

AUTO - 基礎となる DB に応じて ID カラム、シーケンス、またはテーブルのいずれか

TABLE - ID を保持するテーブル

IDENTITY - ID カラム

SEQUENCE - シーケンス

@AttributeOverrides( { @AttributeOverride(name="city", column = @Column(name="fld_city") ), @AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ), @AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") ) //nationality columns in homeAddress are overridden } ) Address homeAddress;

Hibernate Annotations リファレンスガイドリファレンスガイド

14

Page 19: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Hibernate は、基本的な EJB3 のものよりも多くの ID ジェネレータを提供します。詳細については、「Hibernate Annotation 拡張機能」 を参照してください。

以下の例は、SEQ_STORE 設定 (以下参照) を使用したシーケンスジェネレータを示しています。

次の例では、ID ジェネレータが使用されています。

AUTO ジェネレータはポータブルなアプリケーションに推奨されるタイプです (複数の DB ベンダー間)。ジェネレータ属性を持つ複数の @Id マッピングに対して ID 生成の設定を共有できます。@SequenceGenerator と @TableGenerator を使用して複数の設定を利用できます。ジェネレータのスコープはアプリケーションまたはクラスのいずれかです。クラスが定義されたジェネレータは、そのクラス以外で不可視であり、アプリケーションレベルのジェネレータよりも優先されます。アプリケーションレベルのジェネレータは XML レベルで定義されます (4章XML を使用したメタデータのオーバーライド を参照)。

ジェネレータを定義するために JPA XML (META-INF/orm.xml と同様) が使用された場合は、EMP_GEN と SEQ_GEN はアプリケーションレベルのジェネレータになります。EMP_GENは、max_lo が 20 の hilo アルゴリズムを使用してテーブルベースの ID ジェネレータを定義します。hi

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")public Integer getId() { ... }

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)public Long getId() { ... }

<table-generator name="EMP_GEN" table="GENERATOR_TABLE" pk-column-name="key" value-column-name="hi" pk-column-value="EMP" allocation-size="20"/>

//and the annotation equivalent

@javax.persistence.TableGenerator( name="EMP_GEN", table="GENERATOR_TABLE", pkColumnName = "key", valueColumnName = "hi" pkColumnValue="EMP", allocationSize=20)

<sequence-generator name="SEQ_GEN" sequence-name="my_sequence" allocation-size="20"/>

//and the annotation equivalent

@javax.persistence.SequenceGenerator( name="SEQ_GEN", sequenceName="my_sequence", allocationSize=20)

第第3章章 エンティティエンティティ BEAN

15

Page 20: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

value は table "GENERATOR_TABLE" に保持されます。情報は、pkColumnName "key" が pkColumnValue "EMP" に等しく、カラム valueColumnName "hi" に次に使用される high value が含まれる行に保持されます。

SEQ_GEN は my_sequence という名前のシーケンスを使用してシーケンスジェネレータを定義します。このシーケンスベースの hilo アルゴリズムに使用されるアロケーションサイズは 20 です。このバージョンの Hibernate Annotations はシーケンスジェネレータで initialValue を処理しないことに注意してください。デフォルトのアロケーションサイズは 50 です。したがって、シーケンスを使用し、常にその値を取得したい場合は、アロケーションサイズを 1 に設定する必要があります。

注記

パッケージレベル定義は EJB 3.0 仕様でサポートされなくなりました。ただし、@GenericGenerator をパッケージレベルで使用できます (「Identifier」 を参照)。

次の例は、クラススコープのシーケンスジェネレータの定義を示しています。

このクラスは my_sequence という名前のシーケンスを使用し、SEQ_STORE ジェネレータは他のクラスで不可視になります。他の例については、org.hibernate.test.annotations.id パッケージで HibernateAnnotations テストをチェックできます。

複数の構文を使用して復号プライマリキーを定義できます。

コンポーネントプロパティを @Id としてアノテートし、コンポーネントクラスを@Embeddable にします。

コンポーネントプロパティを @EmbeddedId としてアノテートします。

クラスを @IdClass としてアノテートし、プライマリキーで関連するエンティティの各プロパティを @Id でアノテートします。

@IdClass は、EJB2 開発者にとっては非常に一般的ですが、Hibernate ユーザーにとっては新しいものである可能性があります。複合プライマリキークラスはエンティティクラスの複数のフィールドまたはプロパティに対応し、プライマリキークラスのプライマリキーフィールドまたはプロパティの名前とエンティティクラスのこれらの名前およびタイプは同じである必要があります。以下に例を示します。

@[email protected]( name="SEQ_STORE", sequenceName="my_sequence")public class Store implements Serializable { private Long id;

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE") public Long getId() { return id; }}

@Entity@IdClass(FootballerPk.class)public class Footballer { //part of the id key @Id public String getFirstname() { return firstname;

Hibernate Annotations リファレンスガイドリファレンスガイド

16

Page 21: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

すでにご覧になったように、@IdClass は対応するプライマリキークラスを参照します。

EJB3 仕様ではサポートされていませんが、Hibernate では、複合 ID 内の関係を定義できます。このためには通常のアノテーションを使用してください。

}

public void setFirstname(String firstname) { this.firstname = firstname; }

//part of the id key @Id public String getLastname() { return lastname; }

public void setLastname(String lastname) { this.lastname = lastname; }

public String getClub() { return club; }

public void setClub(String club) { this.club = club; }

//appropriate equals() and hashCode() implementation}

@Embeddablepublic class FootballerPk implements Serializable { //same name and type as in Footballer public String getFirstname() { return firstname; }

public void setFirstname(String firstname) { this.firstname = firstname; }

//same name and type as in Footballer public String getLastname() { return lastname; }

public void setLastname(String lastname) { this.lastname = lastname; }

//appropriate equals() and hashCode() implementation}

@Entity@AssociationOverride( name="id.channel", joinColumns =

第第3章章 エンティティエンティティ BEAN

17

Page 22: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.2.4. 継承のマッピング

EJB3 は 3 つのタイプの継承をサポートします。

クラス方針ごとのテーブル: Hibernate の <union-class> エレメント

クラス階層ごとに単一のテーブル方針 (Single Table per Class Hierarchy Strategy): Hibernateの <subclass> エレメント

結合サブクラス方針 (Joined Subclass Strategy): Hibernate の <joined-subclass> エレメント

選択された方針は、@Inheritance アノテーションを使用して階層の最上位のエンティティのクラスレベルで宣言されます。

注記

インターフェースのアノテーションは現在サポートされていません。

3.2.4.1. クラスごとのテーブル

この方針には、EJB3 仕様、Hibernate リファレンスドキュメンテーション、Hibernate in Action などで説明された多くの欠点 (特に、ポリモーフィックなクエリや関係に関する問題) があります。Hibernateでは、SQL UNION クエリを使用してこの方針を実装することによりこれらのほとんどの問題を回避しています。

この方針は 1 対多の関係 (双方向である場合) をサポートします。この方針は IDENTITY ジェネレータ方針をサポートしません。ID は複数のテーブルで共有する必要があります。したがって、この方針を使用する場合は、AUTO と IDENTITY を使用しないでください。

3.2.4.2. クラス階層ごとの単一テーブル

すべてのスーパークラスおよびサブクラスのすべてのプロパティは同じテーブルにマップされ、インスタンスは特殊な判別子カラムによって区別されます。

@JoinColumn(name="chan_id") )public class TvMagazin { @EmbeddedId public TvMagazinPk id; @Temporal(TemporalType.TIME) Date time;}

@Embeddablepublic class TvMagazinPk implements Serializable { @ManyToOne public Channel channel; public String name; @ManyToOne public Presenter presenter;}

@Entity@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)public class Flight implements Serializable {

@Entity

Hibernate Annotations リファレンスガイドリファレンスガイド

18

Page 23: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Plane はスーパークラスであり、継承方針 InheritanceType.SINGLE_TABLE を定義します。また、@DiscriminatorColumn アノテーションを使用して判別子カラムを定義し、判別子カラムは判別子タイプを定義することもできます。最後に、@DiscriminatorValue アノテーションは階層のクラスを区別するために使用される値を定義します。これらすべての属性は適切なデフォルトの値を持ちます。判別子カラムのデフォルト名は、 DTYPE です。デフォルトの判別子の値はDiscriminatorType.STRING のエンティティ名 (@Entity.name で定義済み) です。A320 はサブクラスです。デフォルト値を使用したくない場合にのみ、判別子の値を定義する必要があります。方針と判別子タイプは暗黙的です。

@Inheritance と @DiscriminatorColumn はエンティティ階層の最上位で定義する必要があります。

3.2.4.3. 結合サブクラス

@PrimaryKeyJoinColumn アノテーションと @PrimaryKeyJoinColumns アノテーションは、結合サブクラステーブルのプライマリキーを定義します。

上記のすべてのエンティティは JOINED 方針を使用し、Ferry テーブルは同じプライマリキー名を使用して Boat テーブルと結合されます。AmericaCupClass テーブルは結合条件 Boat.id = AmericaCupClass.BOAT_ID を使用して Boat と結合されます。

3.2.4.4. スーパークラスからのプロパティの継承

技術的なスーパークラスまたはビジネスに関連するスーパークラスを使用して、これらを通常のマップエンティティ (つまり、このエンティティに固有のテーブルではない) として含めずに共通のプロパティを共有することは役に立つ場合があります。このために、プロパティを @MappedSuperclass としてマップできます。

@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn( name="planetype", discriminatorType=DiscriminatorType.STRING)@DiscriminatorValue("Plane")public class Plane { ... }

@Entity@DiscriminatorValue("A320")public class A320 extends Plane { ... }

@Entity@Inheritance(strategy=InheritanceType.JOINED)public class Boat implements Serializable { ... }

@Entitypublic class Ferry extends Boat { ... }

@Entity@PrimaryKeyJoinColumn(name="BOAT_ID")public class AmericaCupClass extends Boat { ... }

@MappedSuperclasspublic class BaseEntity { @Basic

第第3章章 エンティティエンティティ BEAN

19

Page 24: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

データベースでは、この階層は id カラム、lastUpdate カラム、 および lastUpdater カラムを持つ Order テーブルとして表されます。組込みのスーパークラスプロパティマッピングはエンティティサブクラスにコピーされます。ただし、組込み可能なスーパークラスは階層のルートではないことに注意してください。

注記

@MappedSuperclass としてマップされていないスーパークラスからのプロパティは無視されます。

注記

Hibernate アノテーション @AccessType を使用しない限り、アクセスタイプ (フィールドまたはメソッド) はルートエンティティから継承されます。

注記

同じ表記法は、スーパークラスからのプロパティを保持するために @Embeddable オブジェクトに適用できます。また、これを行うには @MappedSuperclass を使用する必要があります (ただし、これを標準的な EJB3 機能と見なさないでください)。

注記

クラスを、マップされた継承階層の中間の @MappedSuperclass として指定することができます。

注記

@MappedSuperclass と @Entity でアノテートされていない階層のクラスは無視されます。

@AttributeOverride アノテーションを使用すると、ルートエンティティレベルのエンティティスーパークラスで定義されたカラムをオーバーライドできます。

@Temporal(TemporalType.TIMESTAMP) public Date getLastUpdate() { ... } public String getLastUpdater() { ... } ...}

@Entity class Order extends BaseEntity { @Id public Integer getId() { ... } ...}

@MappedSuperclasspublic class FlyingObject implements Serializable {

public int getAltitude() { return altitude; }

Hibernate Annotations リファレンスガイドリファレンスガイド

20

Page 25: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

altitude プロパティはテーブル Plane の fld_altitude カラムで保持され、推進関係は fld_propulsion_fk 外部キーカラムで具体化されます。

@Entity クラス の @AttributeOverride および @AssociationOverride、@MappedSuperclass クラス、@Embeddable オブジェクトを参照するプロパティを定義できます。

3.2.5. エンティティ Bean 関係のマッピング

3.2.5.1. 1 対 1

エンティティ Bean は、@OneToOne を使用して 1 対 1 の関係で関連付けることができます。1 対 1 の関係には 3 つの種類があります。1 つは、関連付けられたエンティティが同じプライマリキー値を共有する場合、もう 1 つは、外部キーがいずれかのエンティティにより保持される場合 (1 対 1 の多様性をシミュレートするためにデータベースのこの FK カラムは制約する必要があることに注意してください)、最後は 2 つのエンティティ間のリンクを保存するために関係テーブルが使用される場合 (1 対 1 の多様性を確保するために各 fk に対して一意の制約を定義する必要があります) です。

最初に、共有されたプライマリキーを使用して実際の 1 対 1 関係をマップします。

@Transient public int getMetricAltitude() { return metricAltitude; }

@ManyToOne public PropulsionType getPropulsion() { return metricAltitude; } ...}

@Entity@AttributeOverride( name="altitude", column = @Column(name="fld_altitude") )@AssociationOverride( name="propulsion", joinColumns = @JoinColumn(name="fld_propulsion_fk") )public class Plane extends FlyingObject { ...}

@Entitypublic class Body { @Id public Long getId() { return id; }

@OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn public Heart getHeart() { return heart; } ...}

第第3章章 エンティティエンティティ BEAN

21

Page 26: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@PrimaryKeyJoinColumn アノテーションを使用することにより、1 対 1 は true と指定されます。

以下の例では、関連付けられたエンティティは外部キーカラムによってリンクされます。

Customer は Customer テーブル内の passport_fk という名前の外部キーカラムを使用して Passport にリンクされます。結合カラムは @Column アノテーションに似た @JoinColumn アノテーションで宣言されます。結合カラムには referencedColumnName という名前の 1 つまたは複数のパラメータが含まれます。このパラメータは結合に使用される対象エンティティのカラムを宣言します。非プライマリキーカラムに referencedColumnName を使用する場合は、関連付けられたクラスは Serializable である必要があります。また、非プライマリキーカラムに対する referencedColumnName は、単一カラムを持つプロパティにマップする必要があります (他のクラスは動作しない場合があります)。

関係は双方向にすることができます。双方向の関係では、いずれか (一方のみ) が所有者である必要があります。所有者は関係カラムの更新を担当します。関係を担当しない側を宣言するために属性 mappedBy が使用されます。mappedBy は所有者側の関係のプロパティ名を参照します。この例では、これは passport です。示されたように、結合カラムは所有者側ですでに宣言されているため、宣言する必要はありません (宣言しないでください)。

所有者側で @JoinColumn が宣言されていない場合は、デフォルト値が適用されます。所有者テーブルで結合カラムが作成され、その名前は、所有者側の関係の名前、_ (アンダースコア)、および所有者側のプライマリキーカラムの名前が結合されたものになります。この例では、プロパティ名が passport、Passport のカラム ID が id であるため、passport_id になります。

3 つ目の方法 (関係テーブルを使用) は非常に変わったものになります。

@Entitypublic class Heart { @Id public Long getId() { ...}}

@Entitypublic class Customer implements Serializable { @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name="passport_fk") public Passport getPassport() { ... }

@Entitypublic class Passport implements Serializable { @OneToOne(mappedBy = "passport") public Customer getOwner() { ...}

@Entitypublic class Customer implements Serializable { @OneToOne(cascade = CascadeType.ALL) @JoinTable(name = "CustomerPassports", joinColumns = @JoinColumn(name="customer_fk"), inverseJoinColumns = @JoinColumn(name="passport_fk") ) public Passport getPassport() {

Hibernate Annotations リファレンスガイドリファレンスガイド

22

Page 27: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Customer は、CustomerPassports という名前の関係テーブルを使用して Passport にリンクされます。この関係テーブルは、Passport テーブルを参照する passport_fk という名前の外部キーカラム ( inverseJoinColumn により具体化される) と joinColumns 属性により具体化される Customerテーブルを参照する customer_fk という名前の外部キーカラムを持ちます。

このようなマッピングで結合テーブル名と結合カラムを宣言する必要があります。

3.2.5.2. 多対 1

多対 1 の関係はアノテーション @ManyToOne を使用してプロパティレベルで宣言されます。

@JoinColumn 属性はオプションであり、デフォルト値は 1 対 1 の場合と同様に所有者側の関係の名前、_ (アンダースコア)、および所有者側のプライマリキーカラムの名前を結合したものになります。この例では、プロパティ名が company、会社のカラム ID が id であるため、company_id となります。

@ManyToOne はターゲットエンティティ名を示す targetEntity という名前のパラメータを持ちます。ほとんどの場合はデフォルト値 (関係を保存するプロパティのタイプ) で問題ないため、通常は、このパラメータを必要としません。ただし、インターフェースを通常のエンティティの代わりに返り値タイプとして使用する場合、これは役に立ちます。

... }

@Entitypublic class Passport implements Serializable { @OneToOne(mappedBy = "passport") public Customer getOwner() { ...}

@Entity()public class Flight implements Serializable { @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} ) @JoinColumn(name="COMP_ID") public Company getCompany() { return company; } ...}

@Entity()public class Flight implements Serializable { @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, targetEntity=CompanyImpl.class ) @JoinColumn(name="COMP_ID") public Company getCompany() { return company; } ...}

public interface Company { ...

第第3章章 エンティティエンティティ BEAN

23

Page 28: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

また、関係テーブルを使用して多対 1 関係をマップすることもできます。@JoinTable アノテーションにて記述したこの関係テーブルには、エンティティテーブルを再度参照する外部キー(@JoinTable.joinColumns を使用) とターゲットエンティティテーブルを参照する外部キー(@JoinTable.inverseJoinColumns を使用) が含まれます。

3.2.5.3. コレクション

3.2.5.3.1. 概要概要

Collection、List (つまり、インデックスリストではなく順序付きリスト)、Map、および Set をマップできます。EJB3 仕様は、@javax.persistence.OrderBy アノテーションを使用して順序付きリスト (つまり、ロード時に順序が決定されるリスト) をマップする方法を定義します。このアノテーションでは、コレクションの順序を決めるコンマ区切り (ターゲットエンティティ) のプロパティリストがパラメータに格納されます (firstname asc, age desc など)。文字列が空白の場合は、コレクションの順序が id で決められます。

注記

@OrderBy が結合されたクラスで使用された場合 (結合テーブルを使用)、生成されたSQL は MySQL、PostgreSQL、Oracle、および Microsoft SQL で無効になります。これは、order by 句が実際のテーブル名を使用して列を修飾するからです。order by 句はテーブルエイリアスを代わりに使用する必要があります。

実際のインデックス化されたコレクションについては、「Hibernate Annotation 拡張機能」を参照してください。EJB3 では、Maps を、@MapKey(name="myProperty") (myProperty はターゲットエンティティのプロパティ名) を使用する主要なターゲットエンティティプロパティとしてマップできます。@MapKey (プロパティ名なし) を使用する場合は、ターゲットエンティティプライマリキーが使用されます。マップキーは指摘されたプロパティと同じ列を使用します。マップキーを保持するために追加の列は定義されません。これは、マップキーが実際にはターゲットプロパティを表すため、道理にかなっています。キーはロードされたら、プロパティと同期されなくなることに注意してください。つまり、Java モデルでは、プロパティ値を変更すると、キーは自動的に変更されません (実際のマップサポートについては、「Hibernate Annotation 拡張機能」 を参照)。多くの人が、<map> 機能と @MapKey機能を混同しています。これらは異なる機能です。@MapKey にはいくつかの制限があります。詳細については、JIRA トラッキングシステムのフォーラムを確認してください。

Hibernate にはコレクションの複数の表記法があります。

表表3.1 コレクションセマンティクスコレクションセマンティクス

@Entity()public class Flight implements Serializable { @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} ) @JoinTable(name="Flight_Company", joinColumns = @JoinColumn(name="FLIGHT_ID"), inverseJoinColumns = @JoinColumn(name="COMP_ID") ) public Company getCompany() { return company; } ...}

Hibernate Annotations リファレンスガイドリファレンスガイド

24

Page 29: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

セマンティックセマンティック java 表現表現 アノテーションアノテーション

バッグセマンティック java.util.List

java.util.Collection

@org.hibernate.annotations.CollectionOfElements

または @OneToMany

または @ManyToMany

プライマリキーを持つバッグセマンティック (バッグセマンティックの制限なし)

java.util.List, java.util.Collection (@org.hibernate.annotations.CollectionOfElements、@OneToMany、または@ManyToMany) および@CollectionId

リストセマンティック java.util.List (@org.hibernate.annotations.CollectionOfElements または@OneToMany or@ManyToMany) および@org.hibernate.annotations.IndexColumn

セットセマンティック java.util.Set @org.hibernate.annotations.CollectionOfElements、@OneToMany、または@ManyToMany

マップセマンティック java.util.Map (@org.hibernate.annotations.CollectionOfElements、@OneToMany、または@ManyToMany) および (なしまたは@org.hibernate.annotations.MapKey/MapKeyManyToMany (実際のマップサポートの場合) または@javax.persistence.MapKey

EJB3 仕様では、プリミティブ、コアタイプ、または組込みオブジェクトのコレクションはサポートされません。ただし、Hibernate Annotations ではサポートされます (「Hibernate Annotation 拡張機能」を参照)。

@Entity public class City { @OneToMany(mappedBy="city") @OrderBy("streetName") public List<Street> getStreets() { return streets; }...}

@Entity public class Street { public String getStreetName() {

第第3章章 エンティティエンティティ BEAN

25

Page 30: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

したがって、City は、コレクションがロードされたときに streetName (Street の) で並べ替えられた Street のコレクションを持ちます。Software は、キーが Version codeName の Version のマップを持ちます。

コレクションが汎用でない限り、targetEntity を定義する必要があります。これはターゲットエンティティクラスを値として取得するアノテーション属性です。

3.2.5.3.2. 1 対多対多

1 対多関係はアノテーション @OneToMany を使用してプロパティレベルで宣言されます。1 対多関係は双方向にできます。

3.2.5.3.2.1. 双方向双方向

EJB3 仕様では、多対 1 は常に双方向関係の所有者側であるため、1 対多関係は @OneToMany( mappedBy=... ) によってアノテートされます。

return streetName; }

@ManyToOne public City getCity() { return city; } ...}

@Entitypublic class Software { @OneToMany(mappedBy="software") @MapKey(name="codeName") public Map<String, Version> getVersions() { return versions; }...}

@Entity@Table(name="tbl_version")public class Version { public String getCodeName() {...}

@ManyToOne public Software getSoftware() { ... }...}

@Entitypublic class Troop { @OneToMany(mappedBy="troop") public Set<Soldier> getSoldiers() { ...}

Hibernate Annotations リファレンスガイドリファレンスガイド

26

Page 31: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Troop はhas a bidirectional one to many relationship troop プロパティを経由した Soldier を持つ双方向の 1 対多関係を持ちます。mappedBy 側で物理的なマッピングを定義しないでください。

1 対多側を所有者側として双方向の 1 対多をマップするには、mappedBy エレメントを削除し、挿入および更新可能な多対 1 の @JoinColumn を false に設定する必要があります。このソリューションは当然最適化されず、いくつかの追加の UPDATE ステートメントが生成されます。

3.2.5.3.2.2. 一方向一方向

所有されたエンティティの外部キーカラムを使用する一方向 1 対多は、それほど一般的ではなく推奨されません。このような関係 (次項で説明) には結合テーブルを使用することが強く推奨されます。このような関係は @JoinColumn を使用して定義されます。

Customer は、結合カラム CUST_ID を使用する Ticket で一方向関係を示します。

3.2.5.3.2.3. 結合テーブルを使用する一方向結合テーブルを使用する一方向

@Entitypublic class Soldier { @ManyToOne @JoinColumn(name="troop_fk") public Troop getTroop() { ...}

@Entitypublic class Troop { @OneToMany @JoinColumn(name="troop_fk") //we need to duplicate the physical information public Set<Soldier> getSoldiers() { ...}

@Entitypublic class Soldier { @ManyToOne @JoinColumn(name="troop_fk", insertable=false, updatable=false) public Troop getTroop() { ...}

@Entitypublic class Customer implements Serializable { @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="CUST_ID") public Set<Ticket> getTickets() { ...}

@Entitypublic class Ticket implements Serializable { ... //no bidir}

第第3章章 エンティティエンティティ BEAN

27

Page 32: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

結合テーブルを使用する一方向 1 対多が強く推奨されます。この関係は @JoinTable を使用して定義されます。

Trainer は、結合テーブル TrainedMonkeys を使用する Monkey、Trainer (joinColumns) に対する外部キー trainer_id、Monkey (inversejoinColumns) に対する外部キー monkey_id を使用して一方向関係を定義します。

3.2.5.3.2.4. デフォルト値デフォルト値

物理的なマッピングを定義しないと、結合テーブルを使用する一方向 1 対多が使用されます。テーブル名は所有者テーブル名、_、およびもう一方のテーブル名を結合したものです。所有者テーブルを参照する外部キー名は所有者テーブル、_、および所有者プライマリキーカラム名を結合したのものです。もう一方のテーブルを参照する外部キー名は、所有者プロパティ名、_、およびもう一方のプライマリキーカラム名を結合したものです。1 対多を反映するために一意の制約が、もう一方のテーブルを参照する外部キーに追加されます。

Trainer は、結合テーブル Trainer_Tiger を使用する Tiger、Trainer (テーブル名、_、trainerid) に対する外部キー trainer_id、Monkey (プロパティ名、_、Tigerプライマリカラム) に対する外部キー trainedTigers_id を使用して一方向関係を定義します。

3.2.5.3.3. 多対多多対多

3.2.5.3.3.1. 定義定義

多対多関係は、@ManyToMany アノテーションを使用して論理的に定義されます。また、@JoinTable

@Entitypublic class Trainer { @OneToMany @JoinTable( name="TrainedMonkeys", joinColumns = @JoinColumn( name="trainer_id"), inverseJoinColumns = @JoinColumn( name="monkey_id") ) public Set<Monkey> getTrainedMonkeys() { ...}

@Entitypublic class Monkey { ... //no bidir}

@Entitypublic class Trainer { @OneToMany public Set<Tiger> getTrainedTigers() { ...}

@Entitypublic class Tiger { ... //no bidir}

Hibernate Annotations リファレンスガイドリファレンスガイド

28

Page 33: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

アノテーションを使用して関係テーブルと結合条件を定義する必要があります。関係が双方向である場合は、一方が所有者、もう一方が逆の立場である必要があります (つまり、関係テーブルの関係値を更新するときに無視されます)。

これまで多くの宣言と関係の詳細な属性を示しました。次に、@JoinTable 定義について説明します。name、結合カラムのアレイ (アノテーションのアレイは { A, B, C } を使用して定義されます)、逆結合カラムのアレイが定義されます。最後の 2 つは Employee プライマリキー ("もう一方") を参照する関係テーブルのカラムです。

以前に説明したように、もう一方は物理的なマッピングを定義してはいけません。所有者側プロパティ名を含む単純な mappedBy 引数は 2 つをバインドします。

3.2.5.3.3.2. デフォルト値デフォルト値

他の関係と同様に、多対多関係ではほとんどの値が推測されます。一方向多対多の物理的なマッピングを定義しない場合は、次のルールが適用されます。テーブル名は、所有者テーブル名、_、およびもう一方のテーブル名を結合したものです。所有者テーブルを参照する外部キー名は、所有者テーブル名、_、および所有者プライマリキーカラムを結合したものです。もう一方を参照する外部キー名は、所有者プロパティ名、_、およびもう一方のプライマリキーカラムを結合したものです。これらは、一方向 1 対多関係で使用されたものと同じルールです。

@Entitypublic class Employer implements Serializable { @ManyToMany( targetEntity=org.hibernate.test.metadata.manytomany.Employee.class, cascade={CascadeType.PERSIST, CascadeType.MERGE} ) @JoinTable( name="EMPLOYER_EMPLOYEE", joinColumns=@JoinColumn(name="EMPER_ID"), inverseJoinColumns=@JoinColumn(name="EMPEE_ID") ) public Collection getEmployees() { return employees; } ...}

@Entitypublic class Employee implements Serializable { @ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "employees", targetEntity = Employer.class ) public Collection getEmployers() { return employers; }}

@Entitypublic class Store { @ManyToMany(cascade = CascadeType.PERSIST)

第第3章章 エンティティエンティティ BEAN

29

Page 34: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

Store_City は結合テーブルとして使用されます。Store_id カラムは Store テーブルに対する外部キーです。implantedIn_id カラムは City テーブルに対する外部キーです。

双方向多対多で物理的なマッピングを定義しない場合は、次のルールが適用されます。テーブル名は、所有者テーブル名、_、およびもう一方のテーブル名を結合したものです。所有者テーブルを参照する外部キー名は、もう一方のプロパティ名、_、および所有者プライマリキーカラムを結合したものです。もう一方を参照する外部キー名は、所有者プロパティ名、_、およびもう一方のプライマリキーカラムを結合したものです。これらは、一方向 1 対多関係で使用されたものと同じルールです。

Store_Customer は結合テーブルとして使用されます。stores_id カラムは、Store テーブルに対する外部キーです。customers_id カラムはCustomer テーブルに対する外部キーです。

3.2.5.4. カスケード機能を持つトランシティブ永続化

cascade 属性が CascadeType のアレイを値として取得することに気づかれたかもしれません。EJB3のカスケードコンセプトは、Hibernate のトランシティブ永続化およびカスケード機能に非常に類似しています (ただし、セマンティクスとカスケードタイプが若干異なります)。

CascadeType.PERSIST: persist() が呼び出された場合、またはエンティティが管理された場合に、永続 (作成) 操作を関連付けられたエンティティにカスケードします。

CascadeType.MERGE: merge() が呼び出された場合、またはエンティティが管理された場合に、マージ操作を関連付けられたエンティティにカスケードします。

CascadeType.REMOVE: delete() が呼び出された場合に、削除操作を関連付けられたエンティティにカスケードします。

CascadeType.REFRESH: refresh() が呼び出された場合に、更新操作を関連付けられたエンティティにカスケードします。

public Set<City> getImplantedIn() { ... }}

@Entitypublic class City { ... //no bidirectional relationship}

@Entitypublic class Store { @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) public Set<Customer> getCustomers() { ... }}

@Entitypublic class Customer { @ManyToMany(mappedBy="customers") public Set<Store> getStores() { ... }}

Hibernate Annotations リファレンスガイドリファレンスガイド

30

Page 35: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

CascadeType.ALL: 上記のすべて

注記

また、CascadeType.ALL は save-update や lock などの Hibernate 固有の操作もカバーします。詳細については、「カスケード」 を参照してください。

カスケードおよび作成/マージセマンティクスの詳細については、EJB3 仕様の第 6.3 章を参照してください。

3.2.5.5. 関係フェッチング

関連付けられたエンティティを積極的または消極的にフェッチできます。fetch パラメータは、FetchType.LAZY または FetchType.EAGER に設定できます。EAGER は外側の結合セレクトを使用して関連付けられたオブジェクトを取得し、LAZY は関連付けられたオブジェクトが初めてアクセスされた場合にのみセレクトをトリガーします。@OneToMany 関係と @ManyToMany 関係はデフォルトで LAZY に設定され、@OneToOne と @ManyToOne はデフォルトで EAGER に設定されます。静的なフェッチの詳細については、「レイジーオプションとフェッチモード」 を確認してください。

推奨される方法はすべての静的フェッチ定義に対して LAZY を使用し、JPA-QL により動的にこの選択をオーバーライドすることです。JPA-QL は、特定のクエリを実行する場合にレイジーさをオーバーライドできる fetch キーワードを持ちます。これは、パフォーマンスを向上させるのに非常に役に立ち、ケースバイケースで決定されます。

3.2.6. 複合プライマリおよび外部キーのマッピング

複合プライマリキーは組み込みクラスをプライマリキー表現として使用します。したがって、@Id アノテーションと @Embeddable アノテーションを使用します。または、@EmbeddedId アノテーションを使用できます。依存クラスはシリアル化できる必要があり、equals()/hashCode() を実装することに注意してください。また、「ID プロパティのマッピング」 で説明されたように @IdClass を使用することもできます。

または

Hibernate 固有のアノテーション @AccessType が使用されない限り、@Embeddable は所有側エン

@Entitypublic class RegionalArticle implements Serializable {

@Id public RegionalArticlePk getPk() { ... }}

@Embeddablepublic class RegionalArticlePk implements Serializable { ... }

@Entity public class RegionalArticle implements Serializable {

@EmbeddedId public RegionalArticlePk getPk() { ... }}

public class RegionalArticlePk implements Serializable { ... }

第第3章章 エンティティエンティティ BEAN

31

Page 36: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

ティティのアクセスタイプを継承します。複合外部キー (デフォルトのセンシティブな値を使用しない場合) は、基本的に @JoinColumn のアレイである @JoinColumns エレメントを使用して関係に対して定義されます。referencedColumnNames を明示的に表現することは推奨される方法です。この方法に従わないと、Hibernate はユーザーがプライマリキー宣言と同じ順序のカラムを使用すると見なします。

referencedColumnName の明示的な使用に注意してください。

3.2.7. セカンダリテーブルのマッピング

@Entitypublic class Parent implements Serializable { @Id public ParentPk id; public int age;

@OneToMany(cascade=CascadeType.ALL) @JoinColumns ({ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"), @JoinColumn(name="parentLastName", referencedColumnName = "lastName"), @JoinColumn(name="parentFirstName", referencedColumnName = "firstName") }) public Set<Child> children; //unidirectional ...}

@Entitypublic class Child implements Serializable { @Id @GeneratedValue public Integer id;

@ManyToOne @JoinColumns ({ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"), @JoinColumn(name="parentLastName", referencedColumnName = "lastName"), @JoinColumn(name="parentFirstName", referencedColumnName = "firstName") }) public Parent parent; //unidirectional}

@Embeddablepublic class ParentPk implements Serializable { String firstName; String lastName; ...}

Hibernate Annotations リファレンスガイドリファレンスガイド

32

Page 37: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@SecondaryTable または @SecondaryTables クラスレベルアノテーションを使用して、複数のテーブルに対して単一のエンティティ Bean をマップできます。カラムが特定のテーブルに含まれることを表現するには、@Column または @JoinColumn の table パラメータを使用します。

この例では、name は MainCat に含まれます。storyPart1 は Cat1、storyPart2 は Cat2 に含まれます。Cat1 は cat_id を外部キーとして MainCat に結合されます (Cat2 は id を使用します) (つまり、MainCat id カラムが持つのと同じカラム名)。さらに、storyPart2 に対する一意の制約が設定されます。

追加の例については、JBoss EJB 3 チュートリアルまたは Hibernate Annotations ユニットテストスイートを確認してください。

3.3. クエリのマッピング

3.3.Mapping JPAQL/HQL queries. JPAQL/HQL クエリのマッピング

アノテーションを使用して EJBQL/HQL クエリをマップできます。@NamedQuery と @NamedQueriesはクラスレベルまたは JPA XML ファイルで定義できます。ただし、\これらの定義はセッションファクトリ/エンティティぃマネージャファクトリスコープに対してグローバルになります。指定されるクエリは名前と実際のクエリ文字列によって定義されます。

@Entity@Table(name="MainCat")@SecondaryTables({ @SecondaryTable(name="Cat1", pkJoinColumns={ @PrimaryKeyJoinColumn(name="cat_id", referencedColumnName="id") ), @SecondaryTable(name="Cat2", uniqueConstraints={@UniqueConstraint(columnNames={"storyPart2"})}) })public class Cat implements Serializable {

private Integer id; private String name; private String storyPart1; private String storyPart2;

@Id @GeneratedValue public Integer getId() { return id; }

public String getName() { return name; } @Column(table="Cat1") public String getStoryPart1() { return storyPart1; }

@Column(table="Cat2") public String getStoryPart2() { return storyPart2; }

<entity-mappings>

第第3章章 エンティティエンティティ BEAN

33

Page 38: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

また、hints 属性を介して QueryHint のアレイを使用してクエリにいくつかのヒントを提供することもできます。

利用可能な Hibernate のヒント

表表3.2 クエリヒントクエリヒント

ヒントヒント 説明説明

org.hibernate.cacheable クエリがセカンドレベルキャッシュとやりとりを行うべきかどうか (デフォルトでは false に設定される)

org.hibernate.cacheRegion キャッシュリージョン名 (通常はデフォルト値が使用される)

org.hibernate.timeout クエリタイムアウト

org.hibernate.fetchSize 結果セットフェッチサイズ

org.hibernate.flushMode このクエリに使用されるフラッシュモード

org.hibernate.cacheMode このクエリに使用されるキャッシュモード

org.hibernate.readOnly このクエリでロードされるエンティティを読み取り専用モードにするかどうか (デフォルトで false に設定される)

org.hibernate.comment 生成された SQL に追加されたクエリコメント

<named-query name="plane.getAll"> <query>select p from Plane p</query> </named-query> ...</entity-mappings>...

@Entity@NamedQuery(name="night.moreRecentThan", query="select n from Night n where n.date >= :date")public class Night { ...}

public class MyDao { doStuff() { Query q = s.getNamedQuery("night.moreRecentThan"); q.setDate( "date", aMonthAgo ); List results = q.list(); ... } ...}

Hibernate Annotations リファレンスガイドリファレンスガイド

34

Page 39: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.3.2. ネイティブクエリのマッピング

また、ネイティブクエリ (つまり、プレーンな SQL クエリ) をマップすることもできます。これを実現するには、 @SqlResultSetMapping (複数の結果セットマッピングを定義する場合は @SqlResultSetMappings) を使用して SQL 結果セット構造を定義する必要があります。@NamedQuery と同様に、@SqlResultSetMapping はクラスレベルまたは JPA XML ファイルで定義できます。ただし、そのスコープはアプリケーションに対してグローバルになります。

示されたように、resultSetMapping パラメータは @NamedNativeQuery で定義され、定義された @SqlResultSetMapping の名前を表します。結果セットマッピングはこのネイティブクエリによって取得されたエンティティを宣言します。エンティティの各フィールドは SQL エイリアス (またはカラム名) にバインドされます。サブクラスのフィールドを含むエンティティのすべてのフィールドと、関連するエンティティの外部キーカラムは SQL クエリに存在する必要があります。フィールドはクラスプロパティで宣言されたのと同じカラム名にマップされるため、フィールド定義はオプションです。

上記の例では、night&area 名前付きクエリは joinMapping 結果セットマッピングを使用します。このマッピングは Night と Area の 2 つのエンティティを返します。各プロパティは宣言され、カラム名 (クエリにより実際に取得されたカラム名) に関連付けられます。プロパティ/カラムの暗黙的な宣言について説明します。

@NamedNativeQuery(name="night&area", query="select night.id nid, night.night_duration, " + " night.night_date, area.id aid, night.area_id, area.name " + "from Night night, Area area where night.area_id = area.id", resultSetMapping="joinMapping") @SqlResultSetMapping(name="joinMapping", entities={ @EntityResult(entityClass=org.hibernate.test.annotations.query.Night.class, fields = { @FieldResult(name="id", column="nid"), @FieldResult(name="duration", column="night_duration"), @FieldResult(name="date", column="night_date"), @FieldResult(name="area", column="area_id"), discriminatorColumn="disc" }), @EntityResult(entityClass=org.hibernate.test.annotations.query.Area.class, fields = { @FieldResult(name="id", column="aid"), @FieldResult(name="name", column="name") }) } )

@Entity @SqlResultSetMapping(name="implicit", entities=@EntityResult(entityClass=org.hibernate.test.annotations.query.SpaceShip.class)) @NamedNativeQuery(name="implicitSample", query="select * from SpaceShip", resultSetMapping="implicit")public class SpaceShip { private String name; private String model; private double speed;

@Id public String getName() { return name; }

public void setName(String name) { this.name = name;

第第3章章 エンティティエンティティ BEAN

35

Page 40: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

この例では、結果セットマッピングのエンティティメンバのみを定義します。In this example, we onlydescribe the entity member of the result set プロパティとカラムのマッピングはエンティティマッピング値を使用して行われます。この場合は、model プロパティが model_txt カラムにバインドされます。関連するエンティティに対する関係で複合プライマリキーを使用する場合は、各外部キーカラムに対して @FieldResult エレメントを使用する必要があります。@FieldResult 名は関係のプロパティ名、ドット (".")、プライマリキーの名前、フィールド、またはプロパティを結合したものです。

}

@Column(name="model_txt") public String getModel() { return model; }

public void setModel(String model) { this.model = model; }

public double getSpeed() { return speed; }

public void setSpeed(double speed) { this.speed = speed; }}

@Entity@SqlResultSetMapping(name="compositekey", entities=@EntityResult(entityClass=org.hibernate.test.annotations.query.SpaceShip.class, fields = { @FieldResult(name="name", column = "name"), @FieldResult(name="model", column = "model"), @FieldResult(name="speed", column = "speed"), @FieldResult(name="captain.firstname", column = "firstn"), @FieldResult(name="captain.lastname", column = "lastn"), @FieldResult(name="dimensions.length", column = "length"), @FieldResult(name="dimensions.width", column = "width") }), columns = { @ColumnResult(name = "surface"), @ColumnResult(name = "volume") } )

@NamedNativeQuery(name="compositekey", query="select name, model, speed, lname as lastn, fname as firstn, length, width, length * width as surface from SpaceShip", resultSetMapping="compositekey")} )public class SpaceShip { private String name; private String model; private double speed; private Captain captain;

Hibernate Annotations リファレンスガイドリファレンスガイド

36

Page 41: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

private Dimensions dimensions;

@Id public String getName() { return name; }

public void setName(String name) { this.name = name; }

@ManyToOne(fetch= FetchType.LAZY) @JoinColumns( { @JoinColumn(name="fname", referencedColumnName = "firstname"), @JoinColumn(name="lname", referencedColumnName = "lastname") } ) public Captain getCaptain() { return captain; }

public void setCaptain(Captain captain) { this.captain = captain; }

public String getModel() { return model; }

public void setModel(String model) { this.model = model; }

public double getSpeed() { return speed; }

public void setSpeed(double speed) { this.speed = speed; }

public Dimensions getDimensions() { return dimensions; }

public void setDimensions(Dimensions dimensions) { this.dimensions = dimensions; }}

@Entity@IdClass(Identity.class)public class Captain implements Serializable { private String firstname; private String lastname;

@Id

第第3章章 エンティティエンティティ BEAN

37

Page 42: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

注記

寸法プロパティを見ると、Hibernate が組み込みオブジェクトに対してドット表記法をサポートすることがわかります (組み込みオブジェクトをネストすることもできます)。ただし、EJB3 実装はこの機能をサポートする必要はありません。

単一のエンティティを取得する場合やデフォルトのマッピングを使用する場合は、resultSetMapping の代わりに resultClass 属性を使用できます。

一部のネイティブクエリでは、レポートクエリを構築するときなどにスカラー値を返す必要があります。クエリは @ColumnResult を使用して @SqlResultsetMapping でマップできます。実際には同じネイティブクエリでエンティティとスカラーの戻り値を同時に使用することもできます (ただし、これは一般的ではない可能性があります)。

ネイティブクエリに固有な他のクエリヒントが導入されました (クエリがストアドプロシージャであるかどうかに応じて true または false になる org.hibernate.callable)。

3.4. HIBERNATE ANNOTATION 拡張機能

Hibernate 3.1 は EJB 3 エンティティと組み合わせたり、適合したりできるさまざまな追加のアノテーションを提供します。これらは、EJB3 アノテーションの適切な拡張機能として設計されています。

EJB3 機能を強化するために、Hibernate は Hibernate 機能に一致する固有のアノテーションを提供します。org.hibernate.annotations パッケージには、すべてのアノテーション拡張機能が含まれます。

public String getFirstname() { return firstname; }

public void setFirstname(String firstname) { this.firstname = firstname; }

@Id public String getLastname() { return lastname; }

public void setLastname(String lastname) { this.lastname = lastname; }}

@NamedNativeQuery(name="implicitSample", query="select * from SpaceShip", resultClass=SpaceShip.class)public class SpaceShip {

@SqlResultSetMapping(name="scalar", columns=@ColumnResult(name="dimension")) @NamedNativeQuery(name="scalar", query="select length*width as dimension from SpaceShip", resultSetMapping="scalar")

Hibernate Annotations リファレンスガイドリファレンスガイド

38

Page 43: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.1. エンティティ

EJB3 仕様で提供されるもの以外にも Hibernate によりエンティティに対して実行される一部のアクションを調整できます。

@org.hibernate.annotations.Entity は、標準的な @Entity で定義されたもの以外に必要になる可能性がある追加のメタデータを追加します。

mutable: このエンティティが変更可能であるかどうか

dynamicInsert: 挿入にダイナミックな SQL を可能にする

dynamicUpdate: 更新にダイナミックな SQL を可能にする

selectBeforeUpdate: オブジェクトが実際に変更されない限り、Hibernate が SQL UPDATE を実行しないように指定します。

polymorphism: エンティティポリモーフィズムが PolymorphismType.IMPLICIT (デフォルト値)または PolymorphismType.EXPLICIT であるかどうか

optimisticLock: オプティミスティックロッキング方針 (OptimisticLockType.VERSION、OptimisticLockType.NONE、OptimisticLockType.DIRTY、または OptimisticLockType.ALL)

注記

@javax.persistence.Entity は必須であり、@org.hibernate.annotations.Entity を置き換えるものではありません。

いくつかの追加 Hibernate アノテーション拡張機能を以下に示します。

@org.hibernate.annotations.BatchSize を使用すると、このエンティティのインスタンスをフェッチするときにバッチサイズを定義できます (@BatchSize(size=4) )。指定されたエンティティをロードするときに、Hibernate はすべての同じタイプの初期化されていないエンティティをバッチサイズまでの永続コンテキストでロードします。

@org.hibernate.annotations.Proxy はエンティティのレイジー属性を定義します。レイジー (デフォルトで true に設定される) は、クラスがレイジーであるかどうかを定義します。proxyClassNameはプロキシを生成するのに使用するインターフェースです (デフォルトはクラス自体です)。

@org.hibernate.annotations.Where は、このクラスのインスタンスの取得時に使用されるオプションの SQL WHERE 句を定義します。

@org.hibernate.annotations.Check は、DDL ステートメントで定義されたオプションのチェック制約を定義します。

結合サブクラス上の @OnDelete(action=OnDeleteAction.CASCADE): 通常の Hibernate メカニズムの代わりに削除時にSQL カスケード削除を使用します。

@Table(appliesTo="tableName", indexes = { @Index(name="index1", columnNames={"column1", "column2"} ) } ) は、テーブル tableName のカラムに対して定義されたインデックスを作成します。これは、プライマリテーブルまたは任意のセカンダリテーブルに適用できます。@Tables アノテーションを使用すると、さまざまなテーブルにインデックスを適用できます。@javax.persistence.Table または @javax.persistence.SecondaryTable が実行された場合に、このアノテーションが期待されます。

第第3章章 エンティティエンティティ BEAN

39

Page 44: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

注記

@org.hibernate.annotations.Table は @javax.persistence.Table に置き換わるものではなく補完するものです。特にテーブルのデフォルト名を変更する場合は、@org.hibernate.annotations.Table ではなく @javax.persistence.Table を使用する必要があります。

また、@org.hibernate.annotations.Table はセカンダリテーブルの以下のエレメントを定義するためにも使用できます。

fetch: JOIN に設定されている場合 (デフォルト)、Hibernate は内側の結合を使用してクラスまたはスーパークラスにより定義されたセカンダリテーブルを取得し、サブクラスにより定義されたセカンダリテーブルには外側の結合を使用します。セレクトに設定されている場合、Hibernate はサブクラスで定義されたセカンダリテーブルに対して順次選択を使用します (これは行がサブクラスのインスタンスを表す場合にみ行われます)。内側の結合は、クラスとそのスーパークラスにより定義されたセカンダリを取得するために使用されます。

inverse: true の場合、Hibernate はこの結合により定義されたプロパティを挿入または更新しません。デフォルトでは false に設定されます。

optional: 有効な場合 (デフォルト) は、この結合により定義されたプロパティが null ではなく、常に外側の結合を使用してプロパティを取得するときにのみ Hibernate が行を挿入します。

foreignKey: プライマリテーブルを参照するセカンダリテーブルの外部キーを定義します。

@Immutable は、エンティティまたはコレクションを変更不可としてマークします。変更不可のエンティティはアプリケーションによって更新できません。これにより、Hibernate を使用して若干のパフォーマンス最適化を行えます。変更不可エンティティの更新は無視されますが、例外がスローされます。@Immutable はルートエンティティで使用する必要があります。コレクションに配置された @Immutable はコレクションを変更不可にします。つまり、コレクションに対する追加および削除は許可されません。この場合は、HibernateException がスローされます。

@Persister を使用すると、独自のカスタム永続方針を定義できます。たとえば、独自の org.hibernate.persister.EntityPersister のサブクラスを指定したり、ストアドプロシージャコール、フラットファイルに対するシリアル化、LDAP などを使用した永続化を実装するインターフェース org.hibernate.persister.ClassPersister の完全に新しい実装を提供したりできます。

@Entity @BatchSize(size=5) @org.hibernate.annotations.Entity( selectBeforeUpdate = true, dynamicInsert = true, dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL, polymorphism = PolymorphismType.EXPLICIT) @Where(clause="1=1") @org.hibernate.annotations.Table(appliesTo="Forest", indexes = { @Index(name="idx", columnNames = { "name", "length" } ) } ) @Persister(impl=MyEntityPersister.class) public class Forest { ... }

@Entity @Inheritance( strategy=InheritanceType.JOINED ) public class Vegetable { ... }

Hibernate Annotations リファレンスガイドリファレンスガイド

40

Page 45: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.Identifier. Identifier

Hibernate Annotations は、ID を定義する場合に Java Persistence 仕様よりも対象とする範囲が広くなります。

3.4.Identifier.1. ジェネレータ

@org.hibernate.annotations.GenericGenerator とと @org.hibernate.annotations.GenericGenerators を使用すると、を使用すると、Hibernate 固有の固有の ID ジェネレータを定義できます。ジェネレータを定義できます。

strategy は Hibernate3 ジェネレータ方針または IdentifierGenerator 実装の完全修飾クラス名の短い名前です。parameters 属性を使用していくつかのパラメータを追加できます。

標準的なものとは異なり、@GenericGenerator と @GenericGenerators はパッケージレベルアノテーションで使用でき、アプリケーションレベルジェネレータを作成します (JPA XML ファイルに含まれる場合と同様)。

3.4.Identifier.2. @NaturalId

ID プロパティとして使用されない一方で、一部のパラメータ (グループ) はエンティティの自然な ID を

@Entity@OnDelete(action=OnDeleteAction.CASCADE)public class Carrot extends Vegetable { ... }

@Id @GeneratedValue(generator="system-uuid") @GenericGenerator(name="system-uuid", strategy = "uuid") public String getId() {

@Id @GeneratedValue(generator="hibseq")@GenericGenerator(name="hibseq", strategy = "seqhilo", parameters = { @Parameter(name="max_lo", value = "5"), @Parameter(name="sequence", value="heybabyhey") })public Integer getId() {

@GenericGenerators( { @GenericGenerator( name="hibseq", strategy = "seqhilo", parameters = { @Parameter(name="max_lo", value = "5"), @Parameter(name="sequence", value="heybabyhey") } ), @GenericGenerator(...) })package org.hibernate.test.model

第第3章章 エンティティエンティティ BEAN

41

Page 46: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

表します。これは、自然なビジネスキーが存在する場合であってもスキーマがサロゲートプライマリキーを使用する場合 (推奨される方法) に特に当てはまります。Hibernate を使用すると、このような自然なプロパティをマップし、Criteria クエリで再使用できます。自然な ID は @NaturalId とマークされたすべてのプロパティから構成されます。

自然な ID を表すプロパティグループは一意である必要があります (Hibernate はデータベーススキーマが生成された場合に一意の制約を生成します)。

3.4.3. プロパティ

3.4.3.1. アクセスタイプ

アクセスタイプは、エンティティ階層の @Id または @EmbeddedId の位置から推測されます。サブエンティティ、組み込みオブジェクト、およびマップされたスーパークラスはルートエンティティからアクセスタイプを継承します。

Hibernate で、アクセスタイプをオーバーライドして以下のことを行えます。

カスタムアクセスタイプ方針を使用する

アクセスタイプをクラスレベルまたはプロパティレベルで調整する

この動作をサポートするために @AccessType アノテーションが導入されました。アクセスタイプは以下のものに対して定義できます。

エンティティ

スーパークラス

組み込み可能なオブジェクト

@Entitypublic class Citizen { @Id @GeneratedValue private Integer id; private String firstname; private String lastname; @NaturalId @ManyToOne private State state;

@NaturalId private String ssn; ...}

//and later on queryList results = s.createCriteria( Citizen.class ) .add( Restrictions.naturalId().set( "ssn", "1234" ).set( "state", ste ) ) .list();

Hibernate Annotations リファレンスガイドリファレンスガイド

42

Page 47: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

プロパティ

アノテートされたエレメントに対するアクセスタイプはオーバーライドされます。クラスでオーバーライドされた場合は、該当するクラスのすべてのプロパティはアクセスタイプを継承します。ルートエンティティの場合は、階層全体に対してアクセスタイプがデフォルトとして見なされます (クラスまたはプロパティレベルでオーバーライド可能)。

アクセスタイプが "property" としてマークされている場合は、getters がアノテーションに対してスキャンされ、アクセスタイプが "field" としてマークされている場合は、フィールドがアノテーションに対してスキャンされます。それ以外の場合は、@Id または @embeddedId でマークされたエレメントがスキャンされます。

プロパティのアクセスタイプはオーバーライドできますが、アノテートするエレメントは影響されません。たとえば、アクセスタイプ field を持つエンティティは @AccessType("property") でフィールドをアノテートできます。アクセスタイプはこの属性のプロパティとなり、アノテーションをフィールドに対して実行する必要があります。

スーパークラスまたは組み込み可能なオブジェクトがアノテートされない場合は、ルートエンティティアクセスタイプが使用されます (アクセスタイプが中間スーパークラスまたは組み込み可能なオブジェクトに対して定義された場合であっても)。ロシア人形原則は適用されません。

@Entitypublic class Person implements Serializable { @Id @GeneratedValue //access type field Integer id;

@Embedded @AttributeOverrides({ @AttributeOverride(name = "iso2", column = @Column(name = "bornIso2")), @AttributeOverride(name = "name", column = @Column(name = "bornCountryName")) }) Country bornIn;}

@Embeddable@AccessType("property") //override access type for all properties in Countrypublic class Country implements Serializable { private String iso2; private String name;

public String getIso2() { return iso2; }

public void setIso2(String iso2) { this.iso2 = iso2; }

@Column(name = "countryName") public String getName() { return name; }

第第3章章 エンティティエンティティ BEAN

43

Page 48: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.3.2. 式

場合によっては、JVM ではなく計算をデータベースが行ってほしいことがあります。また、ある種の仮想カラムを作成することもできます。カラムに対するプロパティのマッピングの代わりに SQL 断片 (式と呼ばれることもあります) を使用できます。このようなプロパティは読み取り専用です (その値は式断片によって計算されます)。

SQL 断片は、自由に複雑にでき、サブセレクトを含めることもできます。

3.4.3.3. タイプ

@org.hibernate.annotations.Type は、使用されたデフォルトの Hibernate タイプをオーバーライドします。これは、タイプが Hibernate により適切に推測されるため、通常は必要ありません。Hibernate タイプの詳細については、Hibernate リファレンスガイドを参照してください。

@org.hibernate.annotations.TypeDef と @org.hibernate.annotations.TypeDefs を使用すると、タイプ定義を宣言できます。これらのアノテーションはクラスまたはパッケージレベルで配置できます。これらの定義はセッションファクトリに対してグローバルです (クラスレベルで定義された場合であっても)。タイプ定義は使用する前に定義する必要があります。タイプが単一エンティティで使用されている場合は、定義をエンティティ自体に配置できます。それ以外の場合は、注文を処理するエンティティが保証されないため、パッケージレベルで定義を配置することが推奨されます。

注記

パッケージレベルアノテーションは適切なパッケージの package-info.java という名前のファイルに配置されます。アノテーションはパッケージ宣言の前に配置してください。

public void setName(String name) { this.name = name; }}

@Formula("obj_length * obj_height * obj_width")public long getObjectVolume()

//in org/hibernate/test/annotations/entity/package-info.java@TypeDefs( { @TypeDef( name="caster", typeClass = CasterStringType.class, parameters = { @Parameter(name="cast", value="lower") } ) })package org.hibernate.test.annotations.entity;

//in org/hibernate/test/annotations/entity/Forest.javapublic class Forest { @Type(type="caster") public String getSmallText() {

Hibernate Annotations リファレンスガイドリファレンスガイド

44

Page 49: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

複合ユーザータイプを使用する場合は、カラム定義を表現する必要があります。このために @Columnsが導入されました。

3.4.3.4. インデックス

1 つのカラムプロパティで @Index アノテーションを使用して特定のカラムでインデックスを定義できます。columnNames 属性は無視されます。

3.4.3.5. @Parent

組み込み可能なオブジェクト内部で、いずれかのプロパティを所有者エレメントに対するポインターとして定義できます。

...}

@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType")@Columns(columns = { @Column(name="r_amount"), @Column(name="r_currency")})public MonetaryAmount getAmount() { return amount;}

public class MonetaryAmount implements Serializable { private BigDecimal amount; private Currency currency; ...}

@Column(secondaryTable="Cat1")@Index(name="story1index")public String getStoryPart1() { return storyPart1;}

@Entitypublic class Person { @Embeddable public Address address; ...}

@Embeddablepublic class Address { @Parent public Person owner; ...}

person == person.address.owner

第第3章章 エンティティエンティティ BEAN

45

Page 50: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.3.6. 生成されたプロパティ

一部のプロパティは、データベースにより挿入時または更新時に生成されます。Hibernate はこのようなプロパティを処理し、これらのプロパティを読み取るために後続のセレクトをトリガします。

プロパティを @Generated としてアノテートします。挿入可能性または更新可能性が選択した生成方針と競合しないようにする必要があります。GenerationTime.INSERT が選択された場合は、プロパティに挿入可能なカラムを含めないようにする必要があります。また、GenerationTime.ALWAYS が選択された場合は、プロパティに挿入可能なカラムと更新可能なカラムを含めないようにする必要があります。

設計により、@Version プロパティを @Generated(INSERT) にすることはできません。プロパティは NEVER または ALWAYS にする必要があります。

3.4.3.7. @Target

場合によっては、リフレクションにより推測されたタイプは Hibernate で使用するものと異なることがあります。これは、インターフェースが使用される場合に特に当てはまります。@Target を使用してリフレクション推測メカニズムをバイパスできます (関係で利用可能な targetEntity 属性と同様)。

3.4.3.8. オプティミスティックロック

該当するプロパティがダーティな場合 (特にコレクション) であってもバージョン番号の増加を回避することが有用なことがあります。これは、@OptimisticLock(excluded=true) を使用してプロパティ(またはコレクション) をアノテートすることによって可能になります。

正式には、このプロパティの更新でオプティミスティックロックの取得が必要ないように指定されます。

3.4.4. 継承

SINGLE_TABLE は非常に強力な方針ですが、レガシーシステムの場合は、識別子カラムを追加できません。このために、Hibernate は識別子式の表記を導入しました。@DiscriminatorFormula は @DiscriminatorColumn を置き換えるものであり、識別子解決のために SQL 断片を式として使用します (専用カラムを持つ必要はありません)。

@Entitypublic class Antenna { @Id public Integer id; @Generated(GenerationTime.ALWAYS) @Column(insertable = false, updatable = false) public String longitude;

@Generated(GenerationTime.INSERT) @Column(insertable = false) public String latitude;}

@Embedded @Target(OwnerImpl.class) public Owner getOwner() { return owner; }

@Entity

Hibernate Annotations リファレンスガイドリファレンスガイド

46

Page 51: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

デフォルトでは、最上位エンティティを問い合わせる場合に、Hibernate は識別子カラムに制限句を割り当てません。これは、このカラムに階層にマップされない値が含まれる場合(@DiscriminatorValue を使用) に、不便になることがあります。これを回避するには、@ForceDiscriminator を使用します (クラスレベル、@DiscriminatorColumn の次)。Hibernate はエンティティのロード時に利用可能な値をリストします。

JOINED 継承方針のサブクラステーブルに対して Hibernate により生成された外部キー名を定義できます。

Document テーブルから File テーブルへの外部キーには FK_DOCU_FILE という名前が付けられます。

3.4.5. 単一の関係関連のアノテーション

デフォルトでは、予期された関連するエレメントがデータベースにないため (関係カラムの間違った ID)Hibernate が関係を解決できない場合に、Hibernate で例外が発生します。これは、レガシーや不適切に保守されたスキーマに対して不都合な場合があります。@NotFound アノテーションを使用して例外を発生させる代わりに Hibernate がこのようなエレメントを無視するよう要求できます。このアノテーションは @OneToOne (FK を使用)、@ManyToOne、@OneToMany、または @ManyToMany 関係で使用できます。

場合によっては、該当するエンティティが削除されたときにカスケードの削除をデータベースに委任したいことがあります。

@DiscriminatorFormula("case when forest_type is null then 0 else forest_type end")public class Forest { ... }

@Entity@Inheritance(strategy = InheritanceType.JOINED)public abstract class File { ... }

@Entity@ForeignKey(name = "FK_DOCU_FILE")public class Document extends File {

@Entitypublic class Child { ... @ManyToOne @NotFound(action=NotFoundAction.IGNORE) public Parent getParent() { ... } ...}

@Entitypublic class Child { ... @ManyToOne @OnDelete(action=OnDeleteAction.CASCADE) public Parent getParent() { ... } ...}

第第3章章 エンティティエンティティ BEAN

47

Page 52: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

この場合、Hibernate はデータベースレベルでカスケード削除制約を生成します。

外部キー制約 (Hibernate により生成される) は、非常に読み難い名前を持ちます。@ForeignKey を使用することにより制約名をオーバーライドできます。

3.4.5.1. レイジーオプションとフェッチモード

EJB3 には、レイジーロードとフェッチモードを定義する fetch オプションが含まれますが、Hibernate にはさらに多くのこのようなオプションが設定されています。レイジーロードとフェッチ方針を調整するために、いくつかのアノテーションが導入されました。

@LazyToOne: @ManyToOne 関係と @OneToOne 関係に対してレイジーオプションを定義します。LazyToOneOption は PROXY (プロキシベースのレイジーロードを使用)、NO_PROXY (バイトコード拡張ベースのレイジーロードを使用。ビルド時のバイトコード処理が必要)、または FALSE (関係はレイジーではない) のいずれかになります。

@LazyCollection: @ManyToMany 関係と @OneToMany 関係に対するレイジーオプションを定義します。LazyCollectionOption は TRUE (コレクションはレイジーであり、ステータスがアクセスされたときにロードされます)、EXTRA (コレクションはレイジーであり、すべての操作はコレクションロードを回避しようとします。これは、すべてのエレメントのロードが必要でない場合に巨大なコレクションに対して特に役に立ちます)、または FALSE (関係がレイジーでない) のいずれかになります。

@Fetch: 関係をロードするのに使用されるフェッチ方針を定義します。FetchModeは、SELECT (セレクトは関係をロードする必要がある場合にトリガされます)、SUBSELECT (コレクションに対してのみ利用可能。サブセレクト方針を使用。詳細については、Hibernate リファレンスドキュメンテーションを参照)、または JOIN (SQL JOIN を使用して所有者エンティティをロードしつつ関係をロードします) のいずれかになります。JOIN は任意のレイジー属性をオーバーライドします (JOIN 方針を使用してロードされた関係はレイジーにできません)。

Hibernate アノテーションは EJB3 フェッチオプションをオーバーライドします。

表表3.3 同等のレイジーおよびフェッチオプション同等のレイジーおよびフェッチオプション

アノテーションアノテーション レイジーレイジー フェッチフェッチ

@[One|Many]ToOne](fetch=FetchType.LAZY)

@LazyToOne(PROXY) @Fetch(SELECT)

@[One|Many]ToOne](fetch=FetchType.EAGER)

@LazyToOne(FALSE) @Fetch(JOIN)

@Entitypublic class Child { ... @ManyToOne @ForeignKey(name="FK_PARENT") public Parent getParent() { ... } ...}

alter table Child add constraint FK_PARENT foreign key (parent_id) references Parent

Hibernate Annotations リファレンスガイドリファレンスガイド

48

Page 53: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@ManyTo[One|Many](fetch=FetchType.LAZY)

@LazyCollection(TRUE) @Fetch(SELECT)

@ManyTo[One|Many](fetch=FetchType.EAGER)

@LazyCollection(FALSE) @Fetch(JOIN)

アノテーションアノテーション レイジーレイジー フェッチフェッチ

3.4.5.2. @Any

@Any アノテーションは、複数のテーブルからのクラスに対してポリモーフィックな関係を定義します。このタイプのマッピングは常に複数のカラムを必要とします。最初のカラムは関連するエンティティのタイプを保持します。残りのカラムは ID を保持します。このような関係に対して外部キー制約を指定することはできません。したがって、これは、(ポリモーフィックな) 関係をマップする通常の方法ではありません。これは、非常に特殊な場合 (監査ログ、ユーザーセッションデータなど) にのみ使用してください。

@Any アノテーションはメタデータ情報を保持するカラムを定義します。メタデータ情報の値と実際のエンティティタイプをリンクするために、@AnyDef 関係と @AnyDefs 関係が使用されます。

idType はターゲットエンティティ ID プロパティタイプを表し、metaType はメタデータタイプ (通常は String) を表します。

@AnyDef は相互的にし、再利用できます。この場合は @AnyDef をパッケージメタデータとして配置することが推奨されます。

@Any( metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER ) @AnyMetaDef( idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ), @MetaValue( value = "I", targetEntity = IntegerProperty.class ) } ) @JoinColumn( name = "property_id" ) public Property getMainProperty() { return mainProperty; }

//on a package@AnyMetaDef( name="property" idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ), @MetaValue( value = "I", targetEntity = IntegerProperty.class ) } )package org.hibernate.test.annotations.any;

第第3章章 エンティティエンティティ BEAN

49

Page 54: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.6. コレクション関連アノテーション

3.4.6.1. コレクション設定の拡張

設定可能

@BatchSize を使用したコレクションのバッチサイズ

@Where (ターゲットエンティティに適用) または @WhereJoinTable (関係テーブルに適用) を使用する where 句

@Check を使用する check 句

@OrderBy を使用した句別の SQL の順序

@OnDelete(action=OnDeleteAction.CASCADE) を使用した削除カスケード方針

@Immutable を使用したコレクション変更不可能性: 設定された場合は、コレクションのエレメントが変更しないよう指定されます (場合によっては若干のパフォーマンスの最適化がもたらされます)。

@Persister を使用したカスタムコレクションパーシスタ (使用された永続化方針): クラスは org.hibernate.persister.collectionCollectionPersister を実装する必要があります。

また、ソート比較演算子を宣言することもできます。@Sort アノテーションを使用してください。未ソート、自然、またはカスタム比較演算子から比較演算子タイプを指定します。独自の比較演算子実装を使用する場合は、comparator 属性を使用して実装クラスを表現する必要があります。SortedSetまたは SortedMap インターフェースのいずれかを使用する必要があることに注意してください。

詳細については、これらのアノテーションの以前の説明を参照してください。

外部キー制約 (Hibernate により生成される) は、非常に読みにくい名前を持っています。この制約名は @ForeignKey を使用して制約名をオーバーライドできます。このアノテーションはもう一方の制約を参照する関係 inverseName の所有者側に配置する必要があります。

//in a class @Any( metaDef="property", metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER ) @JoinColumn( name = "property_id" ) public Property getMainProperty() { return mainProperty; }

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="CUST_ID") @Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class) @Where(clause="1=1") @OnDelete(action=OnDeleteAction.CASCADE) public SortedSet<Ticket> getTickets() { return tickets; }

@Entitypublic class Woman {

Hibernate Annotations リファレンスガイドリファレンスガイド

50

Page 55: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.6.2. 追加のコレクションタイプ

3.4.6.2.1. リストリスト

EJB3 とは異なり、Hibernate Annotations は実際の List と Array もサポートします。コレクションを通常どおりマップし、@IndexColumn を追加します。このアノテーションを使用すると、インデックスを保持するカラムを定義できます。また、最初のエレメント (ベースインデックスとも呼ばれます) を表すデータベース内のインデックス値を宣言することもできます。通常の値は 0 または 1 です。

注記

@IndexColumn を設定するのを忘れた場合は、バッグセマンティックが適用されます。制限なしでバッグセマンティックを使用する場合は、@CollectionId を使用することを考慮してください。

3.4.6.2.2. Map

Hibernate Annotations は、Map マッピングもサポートします。@javax.persistence.MapKey が設定されてないと、Hibernate は独自のカラムのキーエレメントまたは組み込み可能なオブジェクトをマップします。デフォルトのカラムをオーバーライドするには、キーが基本タイプ (デフォルト値は mapkey) または組み込み可能なオブジェクトの場合は @org.hibernate.annotations.MapKey、キーがエンティティの場合は @org.hibernate.annotations.MapKeyManyToMany を使用できます。

@org.hibernate.annotations.MapKey と @org.hibernate.annotations.MapKeyManyToMany を使用すると、使用するターゲットエレメントをオーバーライドできます。これは、コレクションがジェネリックを使用しない場合 (または、インターフェースを使用する場合) に特に役に立ちます。

... @ManyToMany(cascade = {CascadeType.ALL}) @ForeignKey(name = "TO_WOMAN_FK", inverseName = "TO_MAN_FK") public Set<Man> getMens() { return mens; }}

alter table Man_Woman add constraint TO_WOMAN_FK foreign key (woman_id) references Womanalter table Man_Woman add constraint TO_MAN_FK foreign key (man_id) references Man

@OneToMany(cascade = CascadeType.ALL)@IndexColumn(name = "drawer_position", base=1)public List<Drawer> getDrawers() { return drawers;}

@CollectionOfElements(targetElement = SizeImpl.class) @MapKeyManyToMany(targetEntity = LuggageImpl.class) private Map<Luggage, Size> sizePerLuggage = new HashMap<Luggage, Size>();

第第3章章 エンティティエンティティ BEAN

51

Page 56: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.6.2.3. インデックス化されたコレクションを持つ双方向の関係インデックス化されたコレクションを持つ双方向の関係

一方がインデックス化されたコレクションである双方向の関係(@IndexColumn、@org.hibernate.annotations.MapKey、または @org.hibernate.annotations.MapKeyManyToMany として表されます) は特別な注意が必要です。関連するクラスのプロパティがインデックス化された値を明示的にマップする場合は、mappedByの使用が許可されます。

ただし、子クラスでこのようなプロパティが存在しない場合は、関係を実際に双方向として考えることはできません (もう一方で利用可能でない関係の一方で利用可能な情報が存在します: 索引)。この場合は、コレクションを mappedBy としてマップできません。代わりに、以下のマッピングを使用できます。

このマッピングでは、関係の collection-valued 側が外部キーを更新することを担当します。

@Entitypublic class Parent { @OneToMany(mappedBy="parent") @org.hibernate.annotations.IndexColumn(name="order") private List<Child> children; ...}

@Entitypublic class Child { ... //the index column is mapped as a property in the associated entity @Column(name="order") private int order;

@ManyToOne @JoinColumn(name="parent_id", nullable=false) private Parent parent; ...}

@Entitypublic class Parent { @OneToMany @org.hibernate.annotations.IndexColumn(name="order") @JoinColumn(name="parent_id", nullable=false) private List<Child> children; ...}

@Entitypublic class Child { ... @ManyToOne @JoinColumn(name="parent_id", insertable=false, updatable=false, nullable=false) private Parent parent; ...}

Hibernate Annotations リファレンスガイドリファレンスガイド

52

Page 57: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

3.4.6.2.4. プライマリキー付きのバッグプライマリキー付きのバッグ

他の興味深い機能は、バッグコレクションに対してサロゲートプライマリキーを定義する機能です。これにより、バッグのすべての欠点が取り除かれます。更新および削除が効率的になります (クエリまたはエンティティごとの複数の EAGER バッグ)。このプライマリキーはコレクションテーブルの追加カラムに含まれますが、Java アプリケーションに対して可視状態ではありません。@CollectionId はコレクションを ID バッグとしてマークするために使用されます。また、@CollectionId を使用すると、プライマリキーカラム、プライマリキータイプ、およびジェネレータ方針をオーバーライドすることもできます。この方針は identity またはアプリケーションの定義された任意のジェネレータ名になります。

3.4.6.2.5. エレメントまたは複合エレメントのコレクションエレメントまたは複合エレメントのコレクション

Hibernate Annotations は、コアタイプ (Integer、String、Enums など) のコレクション、組み込み可能なオブジェクトのコレクション、およびプリミティブタイプのアレイもサポートします。これは、エレメントのコレクションと呼ばれます。

エレメントのコレクションは @CollectionOfElements としてアノテートする必要があります(@OneToMany の代替として)。コレクションテーブルを定義するために、@JoinTable アノテーションが関係プロパティで使用されます。joinColumns はエンティティプライマリテーブルとコレクションテーブル間の結合カラムを定義します (inverseJoincolumn は役に立たないため、空白のままにしてください)。コアタイプのコレクションまたはプリミティブタイプのアレイの場合は、関係プロパティの @Column を使用してエレメントカラム定義をオーバーライドできます。また、@AttributeOverrideを使用して組み込み可能なオブジェクトのコレクションをオーバーライドすることもできます。コレクションエレメントに到達するために、属性オーバーライド名に "element" をアペンドする必要があります (コアタイプには "element"、組み込み可能なエレメントのシリアルプロパティには"element.serial")。コレクションのインデックス/キーに到達するには、代わりに "key" をアペンドします。

@Entity@TableGenerator(name="ids_generator", table="IDS")public class Passport { ...

@ManyToMany(cascade = CascadeType.ALL) @JoinTable(name="PASSPORT_VISASTAMP") @CollectionId( columns = @Column(name="COLLECTION_ID"), type=@Type(type="long"), generator = "ids_generator" ) private Collection<Stamp> visaStamp = new ArrayList(); ...}

@Entitypublic class Boy { private Integer id; private Set<String> nickNames = new HashSet<String>(); private int[] favoriteNumbers; private Set<Toy> favoriteToys = new HashSet<Toy>(); private Set<Character> characters = new HashSet<Character>();

@Id @GeneratedValue public Integer getId() { return id; }

@CollectionOfElements public Set<String> getNickNames() {

第第3章章 エンティティエンティティ BEAN

53

Page 58: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

return nickNames; }

@CollectionOfElements @JoinTable( name="BoyFavoriteNumbers", joinColumns = @JoinColumn(name="BoyId") ) @Column(name="favoriteNumber", nullable=false) @IndexColumn(name="nbr_index") public int[] getFavoriteNumbers() { return favoriteNumbers; }

@CollectionOfElements @AttributeOverride( name="element.serial", column=@Column(name="serial_nbr") ) public Set<Toy> getFavoriteToys() { return favoriteToys; }

@CollectionOfElements public Set<Character> getCharacters() { return characters; } ...}

public enum Character { GENTLE, NORMAL, AGGRESSIVE, ATTENTIVE, VIOLENT, CRAFTY}

@Embeddablepublic class Toy { public String name; public String serial; public Boy owner;

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public String getSerial() { return serial; }

public void setSerial(String serial) { this.serial = serial; }

@Parent public Boy getOwner() {

Hibernate Annotations リファレンスガイドリファレンスガイド

54

Page 59: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

組み込み可能なオブジェクトのコレクションで、組み込み可能なオブジェクトは @Parent でアノテートされたプロパティを持つことができます。このプロパティはコレクションを含むエンティティを参照します。

注記

Hibernate Annotations の以前のバージョンは @OneToMany を使用してエレメントのコレクションをマークしていました。セマンティックの不整合のため、アノテーション @CollectionOfElements を導入しました。引き続きエレメントのコレクションを古い方法でマークすることはできますが、この方法は古い方法と見なされ、将来のリリースでサポートされなくなる予定です。

3.4.6.2.6. @ManyToAny

@ManyToAny を使用すると、複数のテーブルからのクラスに対するポリモーフィック関連付けが可能になります。このタイプのマッピングは常に複数のカラムを必要とします。最初のカラムは関連するエンティティのタイプを保持します。残りのカラムは ID を保持します。このような関係に外部キー制約を指定することはできないため、これは (ポリモーフィックな) 関係の通常のマッピング方法ではありません。これは特殊な場合のみ (監査ログ、ユーザーセッションデータなど) 使用してください。

return owner; }

public void setOwner(Boy owner) { this.owner = owner; }

public boolean equals(Object o) { if ( this == o ) return true; if ( o == null || getClass() != o.getClass() ) return false;

final Toy toy = (Toy) o;

if ( !name.equals( toy.name ) ) return false; if ( !serial.equals( toy.serial ) ) return false;

return true; }

public int hashCode() { int result; result = name.hashCode(); result = 29 * result + serial.hashCode(); return result; }}

@ManyToAny( metaColumn = @Column( name = "property_type" ) ) @AnyMetaDef( idType = "integer", metaType = "string", metaValues = { @MetaValue( value = "S", targetEntity = StringProperty.class ),

第第3章章 エンティティエンティティ BEAN

55

Page 60: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@Any と同様に、@ManyToAny は名前付き @AnyDef を使用できます。詳細については、「@Any」 を参照してください。

3.4.7. カスケード

Hibernate は Java Persistence 仕様よりも多くの操作を提供します。@Cascade アノテーションを使用して以下の操作をカスケードできます。

PERSIST

MERGE

REMOVE

REFRESH

DELETE

SAVE_UPDATE

REPLICATE

DELETE_ORPHAN

LOCK

EVICT

これは、SAVE_UPDATE (プレーンな Hibernate Annotations を使用する場合にフラッシュ時にカスケードされる操作。Hibernate EntityManager は仕様ごとにフラッシュ時に PERSIST をカスケードします)。DELETE_ORPHAN は @OneToMany アノテーションにのみ適用され、delete()/remove() 操作を関係から削除されたすべての子オブジェクトに適用するよう指定します。つまり、子は永続化された親により参照解除された場合や DELETE_ORPHAN が使用された場合に、"orphaned" 状態の子が削除されます。

前の例で示されたように @Cascade を使用して @*To*(cascade=...) を補完することが推奨されます。

3.4.8. キャッシュ

データベースアクセスを最適化するために、Hibernate のいわゆる 2 次キャッシュを有効にできます。このキャッシュはエンティティごと、またはコレクションごとに設定できます。

@MetaValue( value = "I", targetEntity = IntegerProperty.class ) } ) @Cascade( { org.hibernate.annotations.CascadeType.ALL } ) @JoinTable( name = "obj_properties", joinColumns = @JoinColumn( name = "obj_id" ), inverseJoinColumns = @JoinColumn( name = "property_id" ) ) public List<Property> getGeneralProperties() {

@OneToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE} ) @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})public Collection<Employer> getEmployers()

Hibernate Annotations リファレンスガイドリファレンスガイド

56

Page 61: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@org.hibernate.annotations.Cache は、該当する 2 次キャッシュのキャッシング方針とリージョンを定義します。このアノテーションはルートエンティティ (サブエンティティでない) とコレクションに対して適用できます。

使用方法: 該当するキャッシュ同時方針 (NONE、READ_ONLY、NONSTRICT_READ_WRITE、READ_WRITE、TRANSACTIONAL)

リージョン (オプション): キャッシュリージョン (デフォルトでクラスの fqcn またはコレクションの fqロール名に設定)

include (オプション): すべてのプロパティを含める場合は all、非レイジープロパティのみを含める場合は non-lazy (デフォルト値は all)。

3.4.9. フィルター

Hibernate では、データに対して任意のフィルターを適用できます。これらのフィルターは実行時に該当するセッションで適用されます。最初にフィルターを定義する必要があります。

@org.hibernate.annotations.FilterDef または @FilterDefs は、同じ名前を使用してフィルターで使用されたフィルター定義を定義します。フィルター定義は name() と parameters() のアレイを持ちます。パラメータにより、実行時にフィルターの動作を調整できます。各パラメータは名前とタイプを持つ @ParamDef により定義されます。また、該当する@FilterDef に対して defaultCondition()パラメータを定義して、個別の @Filter で何も定義されないときに使用するデフォルトの条件を設定することもできます。@FilterDef はクラスまたはパッケージレベルで定義できます。

この時点で、エンティティロードまたはコレクションロードのいずれかに適用される SQL フィルター句を定義する必要があります。エンティティまたはコレクションエレメントのいずれかに対して @Filter が使用および配置されます。

@Entity@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)public class Forest { ... }

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="CUST_ID") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public SortedSet<Ticket> getTickets() { return tickets; }

@Cache( CacheConcurrencyStrategy usage(); String region() default ""; String include() default "all"; )

@Entity @FilterDef(name="minLength", parameters=@ParamDef( name="minLength", type="integer" ) ) @Filters( { @Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length"),

第第3章章 エンティティエンティティ BEAN

57

Page 62: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

コレクションが関係テーブルを関係の表現として使用する場合は、関係テーブル自体またはターゲットエンティティテーブルに対してフィルター条件を適用することもできます。ターゲットエンティティに制約を適用するには、通常の @Filter アノテーションを使用します。ただし、関係テーブルを対象にする場合は、@FilterJoinTable アノテーションを使用します。

3.4.10. クエリ

Hibernate は EJB3 仕様で定義されたものよりも多くの名前付きクエリに関する機能を持つため、@org.hibernate.annotations.NamedQuery、@org.hibernate.annotations.NamedQueries、@org.hibernate.annotations.NamedNativeQuery、および @org.hibernate.annotations.NamedNativeQueries が導入されました。これらは標準バージョンにいくつかの属性を追加し、代替として使用できます。

flushMode: クエリフラッシュモードを定義します (Always、Auto、Commit、または Manual)

cacheable: クエリをキャッシュするかどうか

cacheRegion: クエリがキャッシュされた場合に使用されるキャッシュリージョン

fetchSize: このクエリに対する JDBC ステートメントフェッチサイズ

timeout: クエリタイムアウト

callable: ネイティブクエリに対してのみ (ストアドプロシージャに対して真に設定されます)

comment: コメントがアクティベートされた場合は、クエリがデータベースに送信されたときにコメントが表示されます。

cacheMode: キャッシュ対話モード (get、ignore、normal、put、または refresh)

readOnly: クエリから取得されたエレメントが読み取り専用モードであるかどうか

これらのヒントは、タイプが解除された @QueryHint を使用して標準的な @javax.persistence.NamedQuery アノテーションで設定できます。別のキーの利点は、これらのアノテーションをパッケージレベルで設定できることです。

3.4.11. CRUD 操作に対するカスタム SQL

Hibernate を使用すると、生成された各単一 SQL ステートメントをオーバーライドできます。ネイティブ SQL クエリの使用方法についてはすでに説明しましたが、エンティティのステータスをロードまたは変更するために使用される SQL ステートメントをオーバーライドすることもできます。

@Filter(name="minLength", condition=":minLength <= length") } ) public class Forest { ... }

@OneToMany @JoinTable //filter on the target entity table @Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length") //filter on the association table @FilterJoinTable(name="security", condition=":userlevel >= requiredLevel") public Set<Forest> getForests() { ... }

Hibernate Annotations リファレンスガイドリファレンスガイド

58

Page 63: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

@SQLInsert、@SQLUpdate、@SQLDelete、@SQLDeleteAll はそれぞれ INSERT ステートメント、UPDATE ステートメント、DELETE ステートメント、DELETE ステートメントをオーバーライドしてすべてのエンティティを削除します。

ストアドプロシージャを呼び出す場合は、callable 属性を true (@SQLInsert(callable=true, ...)) に設定してください。

実行が正常に行われたことを確認するために、Hibernate を使用して以下の 3 つの方針のいずれかを定義できます。

NONE: 確認が行われません。ストアドプロシージャは問題発生時に失敗してしまうでしょう。

COUNT: 更新が成功したことを確認する rowcount の使用

PARAM: COUNT と似ていますが、標準的なメカニズムではなく出力パラメータを使用します。

結果チェックスタイルを定義するには、check パラメータ(@SQLUpdate(check=ResultCheckStyle.COUNT, ...)) を使用します。

また、ネイティブ SQL クエリまたは HQL クエリにより SQL ロードステートメントをオーバーライドすることもできます。@Loader アノテーションを使用して名前付きクエリを参照する必要があります。

まったく同じアノテーションセットを使用してコレクション関連のステートメントをオーバーライドできます。

パラメータの順序は重要であり、順序 Hibernate ハンドルプロパティにより定義されます。org.hibernate.persister.entity レベルに対してデバッグロギングを有効にすることにより、予期された順序を確認できます。このレベルを有効にすると、 Hibernate はエンティティの作成、

@Entity@Table(name="CHAOS")@SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)") @SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?") @SQLDelete( sql="DELETE CHAOS WHERE id = ?") @SQLDeleteAll( sql="DELETE CHAOS") @Loader(namedQuery = "chaos")@NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where id= ?", resultClass = Chaos.class)public class Chaos { @Id private Long id; private Long size; private String name; private String nickname;

@OneToMany@JoinColumn(name="chaos_fk")@SQLInsert( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = ? where id = ?") @SQLDelete( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = null where id = ?")private Set<CasimirParticle> particles = new HashSet<CasimirParticle>();

第第3章章 エンティティエンティティ BEAN

59

Page 64: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

更新、削除などに使用される静的な SQL を出力します (予期されたシーケンスを確認するために、アノテーションを使用してカスタム SQL を含めないようにしてください (Hibernate により生成された静的な SQL をオーバーライドします))。

@org.hibernate.annotations.Table と attributes sqlInsert、sqlUpdate、または sqlDelete のいずれかあるいはすべてを使用して、セカンダリテーブルのために SQL ステートメントをオーバーライドすることもできます。

前の例は、該当するテーブル (プライマリまたはセカンダリ) に対してコメントを提供できることも示しています。このコメントは DDL 生成に使用されます。

3.4.12. Tuplizer

org.hibernate.tuple.Tuplizer とそのサブインターフェースは一部のデータの特定の表現を管理します (表現が org.hibernate.EntityMode の場合)。該当するデータ部分がデータ構造と考えられる場合は、このようなデータ構造の作成方法、このようなデータ構造からの値の抽出方法、このようなデータ構造への値の入力方法を知っている tuplizer を使用します。たとえば、POJO エンティティモードの場合、対応する tuplizer はそのコンストラクタを使用して POJO の作成方法と、定義されたプロパティアクセス側を使用して POJO プロパティへのアクセス方法を把握しています。Tuplizer には、org.hibernate.tuple.EntityTuplizer インターフェースと org.hibernate.tuple.ComponentTuplizer インターフェースで表された 2 つの高度なタイプがあります。EntityTuplizers はエンティティに関する上述のコントラクトを管理し、ComponentTuplizers はコンポーネントを管理します。詳細については、Hibernate リファレンスドキュメンテーションを参照してください。

アノテーションで tuplixer を定義するには、適切なエレメントで @Tuplizer アノテーションを使用します。

@Entity@SecondaryTables({ @SecondaryTable(name = "`Cat nbr1`"), @SecondaryTable(name = "Cat2"})@org.hibernate.annotations.Tables( { @Table(appliesTo = "Cat", comment = "My cat table" ), @Table(appliesTo = "Cat2", foreignKey = @ForeignKey(name="FK_CAT2_CAT"), fetch = FetchMode.SELECT, sqlInsert=@SQLInsert(sql="insert into Cat2(storyPart2, id) values(upper(?), ?)") )} )public class Cat implements Serializable {

@Entity@Tuplizer(impl = DynamicEntityTuplizer.class)public interface Cuisine { @Id @GeneratedValue public Long getId(); public void setId(Long id);

public String getName(); public void setName(String name);

@Tuplizer(impl = DynamicComponentTuplizer.class) public Country getCountry(); public void setCountry(Country country);

Hibernate Annotations リファレンスガイドリファレンスガイド

60

Page 65: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

}

第第3章章 エンティティエンティティ BEAN

61

Page 66: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

第4章 XML を使用したメタデータのオーバーライドEJB3 のメタデータに対するプライマリターゲットはアノテーションですが、EJB3 仕様では XML デプロイメント記述子を使用してアノテーションで定義されたメタデータをオーバーライドまたは置換できます。現在のリリースでは、純粋な EJB3 アノテーションのオーバーライドのみがサポートされます。一部のエンティティで Hibernate 固有の機能を使用する場合は、アノテーションまたは hbm ファイルのフォールバックを使用する必要があります。ただし、アノテートされたエンティティと hbm ファイルで定義されたエンティティを組み合わせたり、一致させたりできます。

ユニットテストスイートはいくつかの追加 XML ファイルサンプルを示します。

4.1. 原則

XML デプロイメント記述子構造は、アノテーション構造を反映するよう設計されています。したがって、アノテーション構造を知っている場合は、XML スキーマを使用することが簡単です。

メタデータを定義する 1 つまたは複数の XML ファイルを定義できます。これらのファイルはオーバーライドエンジンによってマージされます。

4.1.1. グローバルレベルメタデータ

すべての XML ファイルで利用可能なグローバルレベルメタデータを定義できます。これらのメタデータをデプロイメントごとに複数回定義しないでください。

xml-mapping-metadata-complete は、すべてのエンティティ、マップされたスーパークラス、および組み込み可能なメタデータを XML から取得することを意味します (つまり、アノテーションを無視します)。

schema / catalog はメタデータのスキーマとカタログの全デフォルト定義をオーバーライドします(XML とアノテーションの両方)。

cascade-persist は、すべての関係がカスケードタイプとして PERSIST を持つことを意味します。この機能を使用しないことを推奨します。

4.1.2. エンティティレベルメタデータ

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" version="1.0">

<persistence-unit-metadata> <xml-mapping-metadata-complete/> <persistence-unit-defaults> <schema>myschema</schema> <catalog>mycatalog</catalog> <cascade-persist/> </persistence-unit-defaults> </persistence-unit-metadata>

Hibernate Annotations リファレンスガイドリファレンスガイド

62

Page 67: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

該当するエンティティでメタデータ情報を定義またはオーバーライドできます。

<?xml version="1.0" encoding="UTF-8"?> <entity-mappings

xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" version="1.0"> <package>org.hibernate.test.annotations.reflection</package>

<entity class="Administration" access="PROPERTY" metadata-

complete="true"> <table name="tbl_admin">

<unique-constraint> <column-name>firstname</column-name> <column-name>lastname</column-name> </unique-constraint> </table> <secondary-table name="admin2">

<primary-key-join-column name="admin_id" referenced-column-name="id"/> <unique-constraint> <column-name>address</column-name> </unique-constraint> </secondary-table> <id-class class="SocialSecurityNumber"/>

<inheritance strategy="JOINED"/>

<sequence-generator name="seqhilo" sequence-name="seqhilo"/>

<table-generator name="table" table="tablehilo"/>

... </entity>

第第4章章 XML を使用したメタデータのオーバーライドを使用したメタデータのオーバーライド

63

Page 68: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

entity-mappings: entity-mappings はすべての XML ファイルのルートエレメントです。xml スキーマを宣言する必要があります。スキーマファイルは hibernate-annotations.jar ファイルに含まれます。Hibernate Annotations によってインターネットアクセスは処理されません。

package (オプション): 該当するデプロイメント記述子ファイルのすべての非修飾クラス名に使用されたデフォルトパッケージ。

entity: エンティティを表します。

metadata-complete はこのエレメントのメタデータ記述が完全であるかどうかを定義します (つまり、クラスレベルで存在するアノテーションを考慮すべきかどうか)。

エンティティが必ず持つclass 属性は、メタデータが適用される java クラスを参照する必要があります。

name 属性を使用してエンティティ名をオーバーライドできます。何も定義されていない場合や、@Entity.name が存在する場合に使用されます (metadata completeが設定されていない場合)。

metadata complete (以下参照) エレメントの場合は、access (FIELD または PROPERTY (デフォルト値)) を定義できます。metadata completeエレメント以外の場合は、access が定義されていないときに @Id 位置が位置を主導し、access が定義されているときに値が使用されます。

table: テーブルプロパティ (名前、スキーマ、カタログ) を宣言できます。何も定義されていない場合は、java アノテーションが使用されます。

例で示されたように 1 つまたは複数の一意の制約を定義できます。

secondary-table: 通常のテーブルと同様にセカンダリテーブルを定義します (ただし、primary-key-join-column エレメントを使用してプライマリキー/外部キーカラムを定義できます)。完全な非メタデータでは、アノテーションセカンダリテーブルは secondary-table 定義が存在しない場合にのみ使用されます。それ以外の場合、アノテーションは無視されます。

id-class: @IdClass の場合と同様に ID クラスを定義します。

inheritance: 階層方針 (JOINED、TABLE_PER_CLASS、SINGLE_TABLE) を定義します。ルートエンティティレベルでのみ利用可能です。

sequence-generator: シーケンスジェネレータを定義します。

table-generator: テーブルジェネレータを定義します。

primary-key-join-column: JOINED 継承方針が使用された場合にサブエンティティのプライマリキー結合カラムを定義します。

<entity class="PostalAdministration"> <primary-key-join-column name="id"/>

... </entity></entity-mappings>

<?xml version="1.0" encoding="UTF-8"?>

Hibernate Annotations リファレンスガイドリファレンスガイド

64

Page 69: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" version="1.0"> <package>org.hibernate.test.annotations.reflection</package> <entity class="Music" access="PROPERTY" metadata-complete="true"> <discriminator-value>Generic</discriminator-value>

<discriminator-column length="34"/> ... </entity> <entity class="PostalAdministration"> <primary-key-join-column name="id"/> <named-query name="adminById">

<query>select m from Administration m where m.id = :id</query> <hint name="org.hibernate.timeout" value="200"/> </named-query> <named-native-query name="allAdmin" result-set-mapping="adminrs">

<query>select *, count(taxpayer_id) as taxPayerNumber from Administration, TaxPayer where taxpayer_admin_id = admin_id group by ...</query> <hint name="org.hibernate.timeout" value="200"/> </named-native-query> <sql-result-set-mapping name="adminrs">

<entity-result entity-class="Administration"> <field-result name="name" column="fld_name"/> </entity-result> <column-result name="taxPayerNumber"/> </sql-result-set-mapping> <attribute-override name="ground">

<column name="fld_ground" unique="true" scale="2"/> </attribute-override> <association-override name="referer"> <join-column name="referer_id" referenced-column-name="id"/> </association-override> ... </entity></entity-mappings>

第第4章章 XML を使用したメタデータのオーバーライドを使用したメタデータのオーバーライド

65

Page 70: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

discriminator-value / discriminator-column: SINGLE_TABLE 継承方針が選択された場合に判別子の値とその値を保持するカラムを定義します。

named-query: 名前付きクエリとクエリに関連するヒントを定義します。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

named-native-query: 名前付きネイティブクエリとその SQL 結果セットマッピングを定義します。または、result-class を定義できます。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

sql-result-set-mapping: 結果セットマッピング構造を定義します。エンティティとカラム両方のマッピングを定義できます。これらの定義はアノテーションで定義されたものに追加されます。2 つの定義が同じ名前の場合は、XML のものが優先されます。

attribute-override / association-override: カラムまたは結合カラムオーバーライドを定義します。このオーバーライドはアノテーションで定義されたものに追加されます。

同じことは <embeddable> and <mapped-superclass> にも適用されます。

4.1.3. プロパティレベルメタデータ

プロパティの XML オーバーライドを定義することはもちろんできます。metadata completeが定義された場合は、追加プロパティ (Java レベル) が無視されます。それ以外の場合は、プロパティのオーバーライドが開始されると、該当するプロパティのすべてのアノテーションが無視されます。すべてのプロパティレベルメタデータは entity/attributes、mapped-superclass/attributes、または embeddable/attributes に存在します。

id、embedded-id、version、embedded、および basic を使用してプロパティをオーバーライドで

<attributes> <id name="id"> <column name="fld_id"/> <generated-value generator="generator" strategy="SEQUENCE"/> <temporal>DATE</temporal> <sequence-generator name="generator" sequence-name="seq"/> </id> <version name="version"/> <embedded name="embeddedObject"> <attribute-override name"subproperty"> <column name="my_column"/> </attribute-override> </embedded> <basic name="status" optional="false"> <enumerated>STRING</enumerated> </basic> <basic name="serial" optional="true"> <column name="serialbytes"/> <lob/> </basic> <basic name="terminusTime" fetch="LAZY"> <temporal>TIMESTAMP</temporal> </basic> </attributes>

Hibernate Annotations リファレンスガイドリファレンスガイド

66

Page 71: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

きます。これらの各エレメントは適切なサブエレメントを持ちます(lob、temporal、enumerated、column)。

4.1.4. 関係レベルメタデータ

関係に対してe XMLオーバーライドを定義できます。すべての関係レベルメタデータがentity/attributes、mapped-superclass/attributes、または embeddable/attributesで動作します。

one-to-many、one-to-one、many-to-one、および many-to-many を使用して関係をオーバーライドできます。これらの各エレメントは適切なサブエレメント (join-table (join-column と inverse-join-column を持つことができる)、join-column、map-key、および order-by) を持つことができます。mapped-by と target-entity は属性として定義できます (適切な場合)。構造がアノテーション構造を再び反映します。すべてのセマンティック情報については、アノテーションを説明する章を参照してください。

<attributes> <one-to-many name="players" fetch="EAGER"> <map-key name="name"/> <join-column name="driver"/> <join-column name="number"/> </one-to-many> <many-to-many name="roads" target-entity="Administration"> <order-by>maxSpeed</order-by> <join-table name="bus_road"> <join-column name="driver"/> <join-column name="number"/> <inverse-join-column name="road_id"/> <unique-constraint> <column-name>driver</column-name> <column-name>number</column-name> </unique-constraint> </join-table> </many-to-many> <many-to-many name="allTimeDrivers" mapped-by="drivenBuses"> </attributes>

第第4章章 XML を使用したメタデータのオーバーライドを使用したメタデータのオーバーライド

67

Page 72: Red Hat JBoss Web Server 1 · クエリ のマッピング 3 ... jpaql/hql クエリのマッピング 3.3.2. ネイティブクエリ ... jpa 仕様では、透過的なオブジェクト

付録A 改訂履歴

改訂改訂 1.0.2-2.1 Wed Feb 11 2015 Lucas CostiRebuild for product name change

改訂改訂 1.0.2-2 Wed Jun 8 2011 Rebecca NewtonEWS 1.0.2.GA の最終ビルド

Hibernate Annotations リファレンスガイドリファレンスガイド

68