HIBERNATE - Relational Persistence for Idiomatic Java
Hibernate Reference Documentation
Hibernateレファレンスドキュメンテーション
3.2.2
Table of Contents(コンテンツテーブル)
Preface(序文)
1. Introduction to Hibernate(Hibernateの紹介)
2. Architecture(アーキテクチャ)
3. Configuration(設定)
4. Persistent Classes(永続クラス)
6.1. Persistent collections(コレクションの永続化)
6.2. Collection mappings(コレクションのマッピング)
6.2.2. Collection elements(コレクション要素)
6.2.3. Indexed collections(インデックス付のコレクション)
6.2.4. Collections of values and many-to-many associations(値のコレクションと多対多関連)
6.2.5. One-to-many associations(一対多関連)
6.3. Advanced collection mappings(高度なコレクション・マッピング)
6.3.1. Sorted collections(ソートされたコレクション)
6.3.2. Bidirectional associations(双方向関連)
6.3.3. Bidirectional associations with indexed collections(インデックス付きコレクションと双方向関連)
6.3.4. Ternary associations(3項関連)
6.3.5. Using an <idbag>(<idbag>の使用)
6.4. Collection examples(コレクションの例)
Chapter 6. Collection Mapping(第6章:コレクションのマッピング)
6.1. Persistent collections(永続コレクション)
Hibernate requires that persistent collection-valued fields be declared as an interface type, for example:
コレクション型のフィールドを永続化するには、そのコレクション型がインターフェイス型である必要があります。例えば、
public class Product {
private String serialNumber;
private Set parts = new HashSet();
public Set getParts() { return parts; }
void setParts(Set parts) { this.parts = parts; }
public String getSerialNumber() { return serialNumber; }
void setSerialNumber(String sn) { serialNumber = sn; }
}
The actual interface might be java.util.Set, java.util.Collection, java.util.List,java.util.Map, java.util.SortedSet, java.util.SortedMap or ... anything you like! (Where "anything you like" means you will have to write an implementation oforg.hibernate.usertype.UserCollectionType.)
実在するインターフェイスにはjava.util.Set、java.util.Collection、java.util.List、java.util.Map、java.util.SortedSet、java.util.SortedMapなどがあります。または、任意のインターフェイスが使えます!(ただし、任意のインターフェイスを使用する場合は、org.hibernate.usertype.UserCollectionTypeの実装クラスを作成する必要があります。)
Notice how we initialized the instance variable with an instance of HashSet. This is the best way to initialize collection valued properties of newly instantiated (non-persistent) instances. When you make the instance persistent - by calling persist(), for example - Hibernate will actually replace the HashSet with an instance of Hibernate's own implementation of Set. Watch out for errors like this:
HashSetのインスタンスを持つインスタンス変数がどのように初期化されるかに注目してみましょう。これは新たに生成された(永続化されていない)コレクション型のプロパティを初期化する最適な方法です。(例えばpersist()により)インスタンスを永続化しようとしたとき、HibernateはHashSetをHibernate独自のSetの実装クラスに置き換えます。このため、次のようなエラーには注意が必要です。
Cat cat = new DomesticCat();
Cat kitten = new DomesticCat();
....
Set kittens = new HashSet();
kittens.add(kitten);
cat.setKittens(kittens);
session.persist(cat);
kittens = cat.getKittens(); // Okay, kittens collection is a Set
(HashSet) cat.getKittens(); // Error!
The persistent collections injected by Hibernate behave like HashMap, HashSet,TreeMap, TreeSet or ArrayList, depending upon the interface type.
Hibernateにより注入された永続性コレクションは、インターフェイス型に応じて、HashMapやHashSet、TreeMap、TreeSet、ArrayListのように振舞います。
Collections instances have the usual behavior of value types. They are automatically persisted when referenced by a persistent object and automatically deleted when unreferenced. If a collection is passed from one persistent object to another, its elements might be moved from one table to another. Two entities may not share a reference to the same collection instance. Due to the underlying relational model, collection-valued properties do not support null value semantics; Hibernate does not distinguish between a null collection reference and an empty collection.
コレクションインスタンスは、値型として普通に振舞います。永続化オブジェクトに参照されたときに自動的に永続化され、参照がなくなったときに自動的に削除されます。もしある永続化オブジェクトから別の永続化オブジェクトに渡されたら、その要素は現在のテーブルから別のテーブルに移動するかもしれません。2つのエンティティが同じコレクションインスタンスを共有してはいけません。リレーショナルモデルをベースにしているため、コレクション型のプロパティにnull値を代入しても意味がありません。つまりHibernateは参照先のないコレクションと空のコレクションを区別しません。
You shouldn't have to worry much about any of this. Use persistent collections the same way you use ordinary Java collections. Just make sure you understand the semantics of bidirectional associations (discussed later).
しかしそれほど心配しなくても構いません。普段使っているJavaのコレクションと同じように、永続化コレクションを使ってください。双方向関連の意味を理解すればよいのです(これは後ほど説明します)。
6.2. Collection mappings(コレクションのマッピング)
The Hibernate mapping element used for mapping a collection depends upon the type of the interface. For example, a <set> element is used for mapping properties of type Set.
コレクションをマッピングするためのマッピング要素は、インターフェイスの型に依存します。例えば、<set>要素はSet型をマッピングするために使います。
<class name="Product">
<id name="serialNumber" column="productSerialNumber"/>
<set name="parts">
<key column="productSerialNumber" not-null="true"/>
<one-to-many class="Part"/>
</set>
</class>
Apart from <set>, there is also <list>, <map>, <bag>, <array> and <primitive-array>mapping elements. The <map> element is representative:
マッピング要素には<set>の他に<list>、<map>、<bag>、<array>、<primitive-array>があります。代表として、<map>要素を下記に示します。
<map
name="propertyName" (1)
table="table_name" (2)
schema="schema_name" (3)
lazy="true|extra|false" (4)
inverse="true|false" (5)
cascade="all|none|save-update|delete|all-delete-orphan|delet(6)e-orphan"
sort="unsorted|natural|comparatorClass" (7)
order-by="column_name asc|desc" (8)
where="arbitrary sql where condition" (9)
fetch="join|select|subselect" (10)
batch-size="N" (11)
access="field|property|ClassName" (12)
optimistic-lock="true|false" (13)
mutable="true|false" (14)
node="element-name|."
embed-xml="true|false"
>
<key .... />
<map-key .... />
<element .... />
</map>
(1)
|
name the collection property name (nameコレクション型であるプロパティ名)
|
(2)
|
table (optional - defaults to property name) (オプション - デフォルトはプロパティ名)the name of the collection table (not used for one-to-many associations)コレクションテーブルの名(一対多関連では使用しません)。)
|
(3)
|
schema (optional) (オプション)the name of a table schema to override the schema declared on the root element (テーブルスキーマ名。ルート要素で宣言されているスキーマより優先されます。)
|
(4)
|
lazy (optional - defaults to true) (オプション - デフォルトはtrue) may be used to disable lazy fetching and specify that the association is always eagerly fetched, or to enable "extra-lazy" fetching where most operations do not initialize the collection (suitable for very large collections) (遅延フェッチを無効にし、関連を常に即時にフェッチにするために使用します。または、「extra-lazy」フェッチを有効にするために使用します。「extra-lazy」フェッチは、ほとんどの操作ではコレクションを初期化しません(非常に大きなコレクションに適しています)。)
|
(5)
|
inverse (optional - defaults to false) (オプション - デフォルトはfalse) mark this collection as the "inverse" end of a bidirectional association (のコレクションが双方向関連の「逆」側であるとマークします。)
|
(6)
|
cascade (optional - defaults to none) (オプション - デフォルトはcascade) enable operations to cascade to child entities (子エンティティへのカスケード操作を有効にします。)
|
(7)
|
sort (optional)(オプション) specify a sorted collection with natural sort order, or a given comparator class (コレクションを自然な順序でソートする場合はnaturalを指定します。あるいはComparatorクラスを指定します。)
|
(8)
|
order-by (optional, JDK1.4 only)(オプション、JDK1.4だけ) specify a table column (or columns) that define the iteration order of the Map, Set or bag, together with an optional asc or desc (Map、Set、bagのイテレーション順序を定義するテーブルカラムを指定すると共に、オプションとしてasc、descを指定します。)
|
(9)
|
where (optional)(オプション) specify an arbitrary SQL WHERE condition to be used when retrieving or removing the collection (useful if the collection should contain only a subset of the available data) (コレクションの検索や削除の際に使う任意のSQLのWHERE条件を指定します(利用可能なデータの一部分だけをコレクションが含むべきときに、これは有用です)。)
|
(10)
|
fetch (optional, defaults to select) (オプション - デフォルトはselect)Choose between outer-join fetching, fetching by sequential select, and fetching by sequential subselect. (外部結合によるフェッチ、順次選択フェッチ(sequential select fetch)、順次サブセレクトフェッチ(sequential subselect fetch)のどれかを選択してください。)
|
(11)
|
batch-size (optional, defaults to 1) (オプション - デフォルトは1) specify a "batch size" for lazily fetching instances of this collection. (コレクションのインスタンスの遅延フェッチのための「バッチサイズ」を指定します。)
|
(12)
|
access (optional - defaults to property) (オプション - デフォルトはproperty): The strategy Hibernate should use for accessing the collection property value. (コレクション型プロパティの値にアクセスするために使用する戦略です。)
|
(13)
|
optimistic-lock (optional - defaults to true) (オプション - デフォルトはtrue): Species that changes to the state of the collection results in increment of the owning entity's version. (For one to many associations, it is often reasonable to disable this setting.) (コレクションの状態を変えることによって、そのオーナーであるエンティティのバージョンがインクリメントされるかを指定します。(一対多関連では、ほとんどの場合において無効に設定するのが妥当です。))
|
(14)
|
mutable (optional - defaults to true) (オプション - デフォルトはtrue): A value offalse specifies that the elements of the collection never change (a minor performance optimization in some cases). (false値は、コレクションの要素が変更されないことを表します(ある場合には、少しパフォーマンスを高めます)。)
|
6.2.1. Collection foreign keys(コレクションの外部キー)
Collection instances are distinguished in the database by the foreign key of the entity that owns the collection. This foreign key is referred to as the collection key column (or columns) of the collection table. The collection key column is mapped by the <key>element.
コレクションのインスタンスは、データベース内では、そのコレクションを所有するエンティティの外部キーによって識別されます。この外部キーはコレクションテーブルのコレクションキーカラムと呼ばれます。コレクションキーカラムは<key>要素によりマッピングします。
There may be a nullability constraint on the foreign key column. For most collections, this is implied. For unidirectional one to many associations, the foreign key column is nullable by default, so you might need to specify not-null="true".
外部キーカラムにはnull設定制約があるかもしれません。ほとんどのコレクションに当てはまるでしょう。単方向の一対多関連において、外部キーカラムはデフォルトでnullを許す設定になっています。よって、not-null="true"を指定する必要があるかもしれません。
<key column="productSerialNumber" not-null="true"/>
The foreign key constraint may use ON DELETE CASCADE.
外部キーの制約がON DELETE CASCADEを使うかもしれません。
<key column="productSerialNumber" on-delete="cascade"/>
See the previous chapter for a full definition of the <key> element.
<key>要素のすべての定義については前の章を参照してください。
6.2.2. Collection elements(コレクション要素)
Collections may contain almost any other Hibernate type, including all basic types, custom types, components, and of course, references to other entities. This is an important distinction: an object in a collection might be handled with "value" semantics (its lifecycle fully depends on the collection owner) or it might be a reference to another entity, with its own lifecycle. In the latter case, only the "link" between the two objects is considered to be state held by the collection.
コレクションは他のHibernateの型のほとんど(すべての基本型、カスタム型、コンポーネント、他のエンティティへの参照)を格納することができます。次の点は重要な違いになります。コレクションに格納されたオブジェクトが「値」セマンティクスとして扱われるのか(ライフサイクルはコレクションのオーナーに完全に依存します)、もしくはそれ自身のライフサイクルを持った別のエンティティへの参照であるかのかという違いです。後者は、2つのオブジェクト間の「リンク」をコレクションに保持していると見なしているだけです。
The contained type is referred to as the collection element type. Collection elements are mapped by <element> or <composite-element>, or in the case of entity references, with <one-to-many> or <many-to-many>. The first two map elements with value semantics, the next two are used to map entity associations.
格納される型はコレクション要素型と呼ばれます。コレクション要素は、<element>または<composite-element>によりマッピングされ、エンティティへの参照の場合には<one-to-many>または<many-to-many>によりマッピングされます。最初の二つは値として要素をマッピングし、次の二つはエンティティの関連をマッピングするのに使われます。
6.2.3. Indexed collections(インデックス付のコレクション)
All collection mappings, except those with set and bag semantics, need an index columnin the collection table - a column that maps to an array index, or List index, or Map key. The index of a Map may be of any basic type, mapped with <map-key>, it may be an entity reference mapped with <map-key-many-to-many>, or it may be a composite type, mapped with <composite-map-key>. The index of an array or list is always of typeinteger and is mapped using the <list-index> element. The mapped column contains sequential integers (numbered from zero, by default).
setとbagを除く全てのコレクションマッピングには、コレクションテーブルの中にインデックス用のカラムが必要です。そのカラムに、配列やListのインデックス、もしくはMapのキーをマッピングします。Mapのインデックスは、<map-key>によりマッピングされた基本型か、<map-key-many-to-many>によりマッピングされたエンティティの関連か、あるいは<composite-map-key>によりマッピングされたコンポジット型になります。配列かリストのインデックスは、常にinteger型で、<list-index>要素によりマッピングします。マッピングされたカラムにはシーケンシャルな整数を格納します(デフォルトでは0から番号が付けられます)。
<list-index
column="column_name" (1)
base="0|1|..."/>
(1)
|
column_name (required)(必須): The name of the column holding the collection index values. (コレクションインデックスの値を保持するカラムの名前。)
|
(1)
|
base (optional, defaults to 0)(オプション、デフォルトは0): The value of the index column that corresponds to the first element of the list or array.( リストもしくは配列の最初の要素に該当するインデックスカラムの値。)
|
<map-key
column="column_name" (1)
formula="any SQL expression" (2)
type="type_name" (3)
node="@attribute-name"
length="N"/>
(1)
|
column (optional)(オプション): The name of the column holding the collection index values.( column(オプション): コレクションインデックスの値を保持するカラム名。)
|
(2)
|
formula (optional)(オプション): A SQL formula used to evaluate the key of the map. (formula(オプション): Mapのキーを評価するのに使われるSQL式。)
|
(3)
|
type (reguired)(必須): The type of the map keys. (Mapキーの型)
|
<map-key-many-to-many
column="column_name" (1)
formula="any SQL expression" (2)(3)
class="ClassName"
/>
(1)
|
column (optional)(オプション): The name of the foreign key column for the collection index values.( コレクションインデックスの値のための外部キーカラム名。)
|
(2)
|
formula (optional)(オプション): A SQL formula used to evaluate the foreign key of the map key. (Mapのキーのための外部キーを評価するために使うSQL式。)
|
(3)
|
class (required)(必須): The entity class used as the map key. (Mapのキーとして使われるエンティティクラス。)
|
If your table doesn't have an index column, and you still wish to use List as the property type, you should map the property as a Hibernate <bag>. A bag does not retain its order when it is retrieved from the database, but it may be optionally sorted or ordered.
もしテーブルにインデックスカラムがなくても、プロパティ型としてListを使いたければ、\Hibernateの<bag>としてプロパティをマッピングします。bagはデータベースから復元される時、順序を保持しません。しかし、(メモリ上で)ソートしたり、(SQLで)順序付けしたり(order by)することもできます。
There are quite a range of mappings that can be generated for collections, covering many common relational models. We suggest you experiment with the schema generation tool to get a feeling for how various mapping declarations translate to database tables.
多くの一般的なリレーショナルモデルをカバーしたために、コレクションのために利用できるマッピングにはかなりの幅があります。様々なマッピング宣言がどのようにデータベーステーブルに変換されるかを知るために、スキーマ生成ツールを使ってみると良いでしょう。
6.2.4. Collections of values and many-to-many associations(値のコレクションと多対多関連)
Any collection of values or many-to-many association requires a dedicated collection table with a foreign key column or columns, collection element column or columns and possibly an index column or columns.
値のコレクションや多対多関連は、専用のコレクションテーブルが必要です。このテーブルは、外部キーカラムと、コレクション要素のカラムと、場合によってはインデックスカラムを持ちます。
For a collection of values, we use the <element> tag.
値のコレクションのために、<element>タグを使用します。
<element
column="column_name" (1)
formula="any SQL expression" (2)
type="typename" (3)
length="L"
precision="P"
scale="S"
not-null="true|false"
unique="true|false"
node="element-name"
/>
(1)
|
column (optional)(オプション): The name of the column holding the collection element values.( コレクションの要素の値を保持するカラム名。)
|
(2)
|
formula (optional)(オプション): An SQL formula used to evaluate the element. (要素を評価するために使うSQL式。)
|
(3)
|
type (required)(必須): The type of the collection element. (コレクションの要素の型。)
|
A many-to-many association is specified using the <many-to-many> element.
多対多関連は<many-to-many>要素で指定します。
<many-to-many
column="column_name" (1)
formula="any SQL expression" (2)
class="ClassName" (3)
fetch="select|join" (4)
unique="true|false" (5)
not-found="ignore|exception" (6)
entity-name="EntityName" (7)
property-ref="propertyNameFromAssociatedClass" (8)
node="element-name"
embed-xml="true|false"
/>
(1)
|
column (optional)(オプション): The name of the element foreign key column. (外部キーカラムの要素の名前。)
|
(2)
|
formula (optional)(オプション): An SQL formula used to evaluate the element foreign key value. (外部キー値の要素を評価するために使うSQL式。)
|
(3)
|
class (required)(オプション): The name of the associated class. (関連クラスの名前。)
|
(4)
|
fetch (optional - defaults to join)(オプション - デフォルトはjoin): enables outer-join or sequential select fetching for this association. This is a special case; for full eager fetching (in a single SELECT) of an entity and its many-to-many relationships to other entities, you would enable join fetching not only of the collection itself, but also with this attribute on the <many-to-many> nested element. (関連のために、外部結合か順次選択フェッチを有効にします。これは特殊なケースですが、エンティティと他のエンティティとの多対多関係を(1つのSELECTにより)完全に即時にフェッチするためには、そのコレクション自体だけでなく、ネストした要素である<many-to-many>のこの属性についてもjoinフェッチを有効する必要があります。)
|
(5)
|
unique (optional)(オプション): Enable the DDL generation of a unique constraint for the foreign-key column. This makes the association multiplicity effectively one to many. (外部キーカラムのユニーク制約のDDL生成を有効にします。これは、関連の多重度を事実上一対多にします。)
|
(6)
|
not-found (optional - defaults to exception)(オプション - デフォルトはexception): Specifies how foreign keys that reference missing rows will be handled: ignore will treat a missing row as a null association. (not-found(オプション - デフォルトはexception)参照先の行がない外部キーをどのように扱うかを指定します。ignoreにすると、行がないことを関連が無いものとして扱います。)
|
(7)
|
entity-name (optional)(オプション): The entity name of the associated class, as an alternative to class. (classの代替である関連クラスのエンティティ名。classの代わりに指定する、関連クラスのエンティティ名。)
|
(8)
|
property-ref: (optional)(オプション) The name of a property of the associated class that is joined to this foreign key. If not specified, the primary key of the associated class is used. (この外部キーに結合する関連クラスのプロパティ名。指定しなかった場合は、関連クラスの主キーを使います。)
|
Some examples, first, a set of strings:
以下にいくつか例を示しますまずはStringのsetに関しての例です。
<set name="names" table="person_names">
<key column="person_id"/>
<element column="person_name" type="string"/>
</set>
A bag containing integers (with an iteration order determined by the order-byattribute):
整数値を含むbag(bagはorder-by属性によって反復順序が定義されています)
<bag name="sizes"
table="item_sizes"
order-by="size asc">
<key column="item_id"/>
<element column="size" type="integer"/>
</bag>
An array of entities - in this case, a many to many association:
エンティティの配列 - この場合、多対多の関連です。
<array name="addresses"
table="PersonAddress"
cascade="persist">
<key column="personId"/>
<list-index column="sortOrder"/>
<many-to-many column="addressId" class="Address"/>
</array>
A map from string indices to dates:
文字列と日付のmap
<map name="holidays"
table="holidays"
schema="dbo"
order-by="hol_name asc">
<key column="id"/>
<map-key column="hol_name" type="string"/>
<element column="hol_date" type="date"/>
</map>
A list of components (discussed in the next chapter):
コンポーネントのリスト(次の章で詳しく説明します)
<list name="carComponents"
table="CarComponents">
<key column="carId"/>
<list-index column="sortOrder"/>
<composite-element class="CarComponent">
<property name="price"/>
<property name="type"/>
<property name="serialNumber" column="serialNum"/>
</composite-element>
</list>
6.2.5. One-to-many associations(一対多関連)
A one to many association links the tables of two classes via a foreign key, with no intervening collection table. This mapping loses certain semantics of normal Java collections:
一対多関連は、コレクション・テーブルを介さず、外部キーにより2つのクラスのテーブルを関連付けます。このマッピングは標準的なJavaのコレクションのセマンティクスをいくつか失います。
? An instance of the contained entity class may not belong to more than one instance of the collection
エンティティクラスのインスタンスは、2つ以上のコレクションのインスタンスに属してはいけません。
? An instance of the contained entity class may not appear at more than one value of the collection index
コレクションに含まれるエンティティクラスのインスタンスは、コレクションインデックスの値として2度以上現れてはいけません。
An association from Product to Part requires existence of a foreign key column and possibly an index column to the Part table. A <one-to-many> tag indicates that this is a one to many association.
ProductからPartへの関連は、Partテーブルへの外部キーカラムと、場合によってはインデックスカラムが必要です。<one-to-many>タグは、これが一対多関連であることを表しています。
<one-to-many
class="ClassName" (1)
not-found="ignore|exception" (2)
entity-name="EntityName" (3)
node="element-name"
embed-xml="true|false"
/>
(1)
|
class (required)(必須): The name of the associated class. (関連クラスの名前。)
|
(2)
|
not-found (optional - defaults to exception)(オプション - デフォルトはexception): Specifies how cached identifiers that reference missing rows will be handled: ignorewill treat a missing row as a null association. (参照先の行がないキャッシュされた識別子をどのように扱うかを指定します。ignoreを指定すると、行がないことを関連がないものとして扱います。)
|
(3)
|
entity-name (optional)(オプション): The entity name of the associated class, as an alternative to class. (classの代替である関連クラスのエンティティ名。classの代わりに指定する、関連クラスのエンティティ名。)
|
Notice that the <one-to-many> element does not need to declare any columns. Nor is it necessary to specify the table name anywhere.
<one-to-many>要素はカラムを宣言する必要がないことに注意してください。同様にテーブル名を指定する必要もありません。
Very important note: If the foreign key column of a <one-to-many> association is declared NOT NULL, you must declare the <key> mapping not-null="true" or use a bidirectional association with the collection mapping marked inverse="true". See the discussion of bidirectional associations later in this chapter.
とても重要な注意:もし<one-to-many>関連の外部キーカラムがNOT NULLと宣言された場合、<key>マッピングにnot-null="true"を宣言するか、コレクションマッピングにinverse="true"を付けた上で、双方向関連を使う必要があります。双方向関連についてはこの章の後のほうで説明します。
This example shows a map of Part entities by name (where partName is a persistent property of Part). Notice the use of a formula-based index.
次の例は、名称(Partの永続的なプロパティであるpartName)によるPartエンティティのmapを表しています。formulaによるインデックスを使っていることに注意してください。
<map name="parts"
cascade="all">
<key column="productId" not-null="true"/>
<map-key formula="partName"/>
<one-to-many class="Part"/>
</map>
6.3. Advanced collection mappings(高度なコレクション・マッピング)
6.3.1. Sorted collections(ソートされたコレクション)
Hibernate supports collections implementing java.util.SortedMap andjava.util.SortedSet. You must specify a comparator in the mapping file:
Hibernateはjava.util.SortedMapとjava.util.SortedSetを実装したコレクションをサポートしています。開発者はマッピング定義ファイルにコンパレータを指定しなければなりません。
<set name="aliases"
table="person_aliases"
sort="natural">
<key column="person"/>
<element column="name" type="string"/>
</set>
<map name="holidays" sort="my.custom.HolidayComparator">
<key column="year_id"/>
<map-key column="hol_name" type="string"/>
<element column="hol_date" type="date"/>
</map>
Allowed values of the sort attribute are unsorted, natural and the name of a class implementing java.util.Comparator.
sort属性に設定できる値はunsortedとnaturalおよび、java.util.Comparatorを実装したクラスの名前です。
Sorted collections actually behave like java.util.TreeSet or java.util.TreeMap.
ソートされたコレクションは実質的にはjava.util.TreeSetやjava.util.TreeMapのように振舞います。
If you want the database itself to order the collection elements use the order-byattribute of set, bag or map mappings. This solution is only available under JDK 1.4 or higher (it is implemented using LinkedHashSet or LinkedHashMap). This performs the ordering in the SQL query, not in memory.
もしデータベース自身にコレクションの要素を並べさせたいなら、setやbag、mapのorder-by属性を使います。この解決法はJDK1.4、もしくはそれ以上のバージョンで利用可能です(LinkedHashSetまたはLinkedHashMapを使って実装されています)。整列はメモリ上ではなく、SQLクエリ内で実行されます。
<set name="aliases" table="person_aliases" order-by="lower(name) asc">
<key column="person"/>
<element column="name" type="string"/>
</set>
<map name="holidays" order-by="hol_date, hol_name">
<key column="year_id"/>
<map-key column="hol_name" type="string"/>
<element column="hol_date type="date"/>
</map>
Note that the value of the order-by attribute is an SQL ordering, not a HQL ordering!
order-by属性の値がSQL命令であって、HQL命令ではないことに注意してください!
Associations may even be sorted by some arbitrary criteria at runtime using a collectionfilter().
関連は、コレクションのfilter()を使うことで、実行時に任意のcriteriaによってソートすることも可能です。
sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();
6.3.2. Bidirectional associations(双方向関連)
A bidirectional association allows navigation from both "ends" of the association. Two kinds of bidirectional association are supported:
双方向関連は関連のどちら「側」からでもナビゲーションできます。2種類の双方向関連がサポートされています。
one-to-many
set or bag valued at one end, single-valued at the other
片側がsetかbag、もう片方が単一値です。
many-to-many
set or bag valued at both ends
両側がsetかbagです。
You may specify a bidirectional many-to-many association simply by mapping two many-to-many associations to the same database table and declaring one end as inverse(which one is your choice, but it can not be an indexed collection).
2つの多対多関連で同じデータベーステーブルをマッピングし、片方をinverseとして宣言することで、双方向の多対多関連を指定することが出来ます(どちらをinverseに選んだとしても、そちら側にはインデックス付きのコレクションは使えません)。
Here's an example of a bidirectional many-to-many association; each category can have many items and each item can be in many categories:
次に双方向の多対多関連の例を示します。各カテゴリは多数のアイテムを持つことができ、各アイテムは多くのカテゴリに属することが出来ます。
<class name="Category">
<id name="id" column="CATEGORY_ID"/>
...
<bag name="items" table="CATEGORY_ITEM">
<key column="CATEGORY_ID"/>
<many-to-many class="Item" column="ITEM_ID"/>
</bag>
</class>
<class name="Item">
<id name="id" column="CATEGORY_ID"/>
...
<!-- inverse end -->
<bag name="categories" table="CATEGORY_ITEM" inverse="true">
<key column="ITEM_ID"/>
<many-to-many class="Category" column="CATEGORY_ID"/>
</bag>
</class>
Changes made only to the inverse end of the association are not persisted. This means that Hibernate has two representations in memory for every bidirectional association, one link from A to B and another link from B to A. This is easier to understand if you think about the Java object model and how we create a many-to-many relationship in Java:
関連のinverse側にのみ行われた変更は永続化されません。これは、Hibernateは全ての双方向関連について、メモリ上に2つの表現を持っているという意味です。つまり一つはAからBへのリンクで、もう一つはBからAへのリンクということです。Javaのオブジェクトモデルについて考え、Javaで双方向関係をどうやって作るかを考えれば、これは理解しやすいです。下記に、Javaでの双方向関連を示します。
category.getItems().add(item); // The category now "knows" about the relationship
item.getCategories().add(category); // The item now "knows" about the relationship
session.persist(item); // The relationship won't be saved!
session.persist(category); // The relationship will be saved
The non-inverse side is used to save the in-memory representation to the database.
関連のinverseではない側は、メモリ上の表現をデータベースに保存するのに使われます。
You may define a bidirectional one-to-many association by mapping a one-to-many association to the same table column(s) as a many-to-one association and declaring the many-valued end inverse="true".
双方向の一対多関連を定義するには、一対多関連を多対一関連と同じテーブルのカラムにマッピングし、多側にinverse="true"と宣言します。
<class name="Parent">
<id name="id" column="parent_id"/>
....
<set name="children" inverse="true">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child">
<id name="id" column="child_id"/>
....
<many-to-one name="parent"
class="Parent"
column="parent_id"
not-null="true"/>
</class>
Mapping one end of an association with inverse="true" doesn't affect the operation of cascades, these are orthogonal concepts!
関連の片側にinverse="true"を設定しても、カスケード操作に影響を与えません。これらは直交した概念です!
6.3.3. Bidirectional associations with indexed collections(インデックス付きコレクションと双方向関連)
A bidirectional association where one end is represented as a <list> or <map> requires special consideration. If there is a property of the child class which maps to the index column, no problem, we can continue using inverse="true" on the collection mapping:
片側が<list>や<map>である双方向関連は、特によく考える必要があります。インデックスカラムにマップされる子クラスのプロパティがある場合は、問題ないです。コレクションのマッピングでinverse="true"を使い続けられます。
<class name="Parent">
<id name="id" column="parent_id"/>
....
<map name="children" inverse="true">
<key column="parent_id"/>
<map-key column="name"
type="string"/>
<one-to-many class="Child"/>
</map>
</class>
<class name="Child">
<id name="id" column="child_id"/>
....
<property name="name"
not-null="true"/>
<many-to-one name="parent"
class="Parent"
column="parent_id"
not-null="true"/>
</class>
But, if there is no such property on the child class, we can't think of the association as truly bidirectional (there is information available at one end of the association that is not available at the other end). In this case, we can't map the collection inverse="true". Instead, we could use the following mapping:
しかし、子クラスにそのようなプロパティがない場合は、関連を真に双方向であると考えることができません(関連の片側に利用できる情報がありますが、もう一方にはありません)。この場合は、コレクションにinverse="true"をマッピングできません。代わりに、次のようなマッピングが使えます。
<class name="Parent">
<id name="id" column="parent_id"/>
....
<map name="children">
<key column="parent_id"
not-null="true"/>
<map-key column="name"
type="string"/>
<one-to-many class="Child"/>
</map>
</class>
<class name="Child">
<id name="id" column="child_id"/>
....
<many-to-one name="parent"
class="Parent"
column="parent_id"
insert="false"
update="false"
not-null="true"/>
</class>
Note that in this mapping, the collection-valued end of the association is responsible for updates to the foreign key. TODO: Does this really result in some unnecessary update statements?
注意: このマッピングでは、関連のコレクション値の側は、外部キーをアップデートする責任があります。TODO:これは本当に必要の無いアップデートステートメントに終わりますか?
6.3.4. Ternary associations(3項関連)
There are three possible approaches to mapping a ternary association. One is to use aMap with an association as its index:
3項関連のマッピングには3つのアプローチがあります。1つ目は関連をインデックスとしてMapを使用するアプローチです。
<map name="contracts">
<key column="employer_id" not-null="true"/>
<map-key-many-to-many column="employee_id" class="Employee"/>
<one-to-many class="Contract"/>
</map>
<map name="connections">
<key column="incoming_node_id"/>
<map-key-many-to-many column="outgoing_node_id" class="Node"/>
<many-to-many column="connection_id" class="Connection"/>
</map>
A second approach is to simply remodel the association as an entity class. This is the approach we use most commonly.
2つ目は単純に関連をエンティティ・クラスとしてモデルを作り直すアプローチで、頻繁に使われます。
A final alternative is to use composite elements, which we will discuss later.
最後はcomposite要素を使うアプローチです。これに関する議論は後ほど行います。
6.3.5. Using an <idbag>(<idbag>の使用)
If you've fully embraced our view that composite keys are a bad thing and that entities should have synthetic identifiers (surrogate keys), then you might find it a bit odd that the many to many associations and collections of values that we've shown so far all map to tables with composite keys! Now, this point is quite arguable; a pure association table doesn't seem to benefit much from a surrogate key (though a collection of composite values might). Nevertheless, Hibernate provides a feature that allows you to map many to many associations and collections of values to a table with a surrogate key.
複合キーは悪いもので、エンティティは人工の識別子(代理キー)を持つべきであるという考え方からは、多対多関連と値のコレクションを複合キーを用いたテーブルへマッピングするのは少し奇妙に感じるかもしれません!確かにこの考え方には議論の余地があります。純粋な関連テーブルは代理キーを使っても利益を得られないように思えるからです(合成値のコレクションは利益があるかもしれませんが)。とはいえ、Hibernateは代理キーを持つテーブルへ多対多関連と値のコレクションをマッピングする機能も備えています。
The <idbag> element lets you map a List (or Collection) with bag semantics.
bagのセマンティックスを持ったList(またはCollection)を<idbag>要素にマッピングできます。
<idbag name="lovers" table="LOVERS">
<collection-id column="ID" type="long">
<generator class="sequence"/>
</collection-id>
<key column="PERSON1"/>
<many-to-many column="PERSON2" class="Person" fetch="join"/>
</idbag>
As you can see, an <idbag> has a synthetic id generator, just like an entity class! A different surrogate key is assigned to each collection row. Hibernate does not provide any mechanism to discover the surrogate key value of a particular row, however.
ご存知のように<idbag>はエンティティ・クラスのように人工的なidジェネレータを持っています!異なる代理キーをそれぞれのコレクションの列に割り当てます。しかしながら、Hibernateはある行の代理キーの値を見つけ出す機構を持っていません。
Note that the update performance of an <idbag> is much better than a regular <bag>! Hibernate can locate individual rows efficiently and update or delete them individually, just like a list, map or set.
<idbag>を更新するパフォーマンスは通常の<bag>よりも良いことに注目してください!Hibernateは個々の行を効果的に見つけることができ、listやmap、setのように個別にその行を更新、削除できます。
In the current implementation, the native identifier generation strategy is not supported for <idbag> collection identifiers.
現在の実装では、nativeというid生成戦略を<idbag>コレクションの識別子に対して使えません。
6.4. Collection examples(コレクションの例)
The previous sections are pretty confusing. So lets look at an example. This class:
これまでの節の説明では理解しにくいので、以下の例を見てください。
package eg;
import java.util.Set;
public class Parent {
private long id;
private Set children;
public long getId() { return id; }
private void setId(long id) { this.id=id; }
private Set getChildren() { return children; }
private void setChildren(Set children) { this.children=children; }
....
....
}
has a collection of Child instances. If each child has at most one parent, the most natural mapping is a one-to-many association:
このクラスはChildインスタンスのコレクションを持っています。もし各々のchildが最大でも一つのparentを持っているならば、最も自然なマッピングは一対多関連です。
<hibernate-mapping>
<class name="Parent">
<id name="id">
<generator class="sequence"/>
</id>
<set name="children">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child">
<id name="id">
<generator class="sequence"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
This maps to the following table definitions:
これは以下のテーブル定義にマッピングします。
create table parent ( id bigint not null primary key )
create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
alter table child add constraint childfk0 (parent_id) references parent
If the parent is required, use a bidirectional one-to-many association:
もしparentが要求されるなら、双方向の一対多関連を使用してください。
<hibernate-mapping>
<class name="Parent">
<id name="id">
<generator class="sequence"/>
</id>
<set name="children" inverse="true">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child">
<id name="id">
<generator class="sequence"/>
</id>
<property name="name"/>
<many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
</class>
</hibernate-mapping>
Notice the NOT NULL constraint:
NOT NULL制約に注意してください。
create table parent ( id bigint not null primary key )
create table child ( id bigint not null
primary key,
name varchar(255),
parent_id bigint not null )
alter table child add constraint childfk0 (parent_id) references parent
Alternatively, if you absolutely insist that this association should be unidirectional, you can declare the NOT NULL constraint on the <key> mapping:
あるいは、もしこの関連は単方向であるべきと強く主張するのであれば、<key>にNOT NULL制約を宣言できます。
<hibernate-mapping>
<class name="Parent">
<id name="id">
<generator class="sequence"/>
</id>
<set name="children">
<key column="parent_id" not-null="true"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child">
<id name="id">
<generator class="sequence"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
On the other hand, if a child might have multiple parents, a many-to-many association is appropriate:
一方で、もしchildが複数のparentを持てるならば、多対多関連が妥当です。
<hibernate-mapping>
<class name="Parent">
<id name="id">
<generator class="sequence"/>
</id>
<set name="children" table="childset">
<key column="parent_id"/>
<many-to-many class="Child" column="child_id"/>
</set>
</class>
<class name="Child">
<id name="id">
<generator class="sequence"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
Table definitions:
テーブル定義は以下のようになります。
create table parent ( id bigint not null primary key )
create table child ( id bigint not null primary key, name varchar(255) )
create table childset ( parent_id bigint not null,
child_id bigint not null,
primary key ( parent_id, child_id ) )
alter table childset add constraint childsetfk0 (parent_id) references parent
alter table childset add constraint childsetfk1 (child_id) references child
For more examples and a complete walk-through a parent/child relationship mapping, see Chapter 21, Example: Parent/Child.
parent/child関係のマッピングについてのより多くの例や完全な手順が必要であれば、Chapter 21, Example: Parent/Child をご覧ください。
Even more exotic association mappings are possible, we will catalog all possibilities in the next chapter.
また、さらに特殊な関連マッピングも可能です。次の章で詳しく述べます。
No comments:
Post a Comment