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 ("anything you like" means you will have to write an implementation of org.hibernate.usertype.UserCollectionType.)

Notice how the instance variable was initialized 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. Be aware of the following errors:

The persistent collections injected by Hibernate behave like HashMap, HashSet, TreeMap, TreeSet or ArrayList, depending on the interface type.

Collections instances have the usual behavior of value types. They are automatically persisted when referenced by a persistent object and are 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 cannot 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.

Use persistent collections the same way you use ordinary Java collections. However, please ensure you understand the semantics of bidirectional associations (these are discussed later).

6.2. Collection-Mappings

Tipp

There are quite a range of mappings that can be generated for collections that cover many common relational models. We suggest you experiment with the schema generation tool so that you understand how various mapping declarations translate to database tables.

The Hibernate mapping element used for mapping a collection depends upon the type of interface. For example, a <set> element is used for mapping properties of type Set.

table (optional - defaults to property name): the name of the collection table. It is not used for one-to-many associations.

schema (optional): the name of a table schema to override the schema declared on the root element

lazy (optional - defaults to true): disables lazy fetching and specifies that the association is always eagerly fetched. It can also be used to enable "extra-lazy" fetching where most operations do not initialize the collection. This is suitable for large collections.

inverse (optional - defaults to false): marks this collection as the "inverse" end of a bidirectional association.

sort (optional): specifies a sorted collection with natural sort order or a given comparator class.

order-by (optional, JDK1.4 only): specifies a table column or columns that define the iteration order of the Map, Set or bag, together with an optional asc or desc.

where (optional): specifies an arbitrary SQL WHERE condition that is used when retrieving or removing the collection. This is useful if the collection needs to contain only a subset of the available data.

optimistic-lock (optional - defaults to true): specifies that changes to the state of the collection results in increments of the owning entity's version. For one-to-many associations you may want to disable this setting.

mutable (optional - defaults to true): a value of false specifies that the elements of the collection never change. This allows for minor performance optimization in some cases.

6.2.1. Collection-Fremdschlüssel

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.

There can 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 may need to specify not-null="true".

6.2.2. Collection-Elemente

Collections can contain almost any other Hibernate type, including: basic types, custom types, components and references to other entities. This is an important distinction. An object in a collection might be handled with "value" semantics (its life cycle fully depends on the collection owner), or it might be a reference to another entity with its own life cycle. In the latter case, only the "link" between the two objects is considered to be a state held by the collection.

6.2.3. Indizierte Collections

All collection mappings, except those with set and bag semantics, need an index column in the collection table. An index column is 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 can be an entity reference mapped with <map-key-many-to-many>, or it can be a composite type mapped with <composite-map-key>. The index of an array or list is always of type integer and is mapped using the <list-index> element. The mapped column contains sequential integers that are numbered from zero by default.

<list-index
column="column_name"
base="0|1|..."/>

column_name (required): the name of the column holding the collection index values.

base (optional - defaults to 0): the value of the index column that corresponds to the first element of the list or array.

column (optional): the name of the foreign key column for the collection index values.

formula (optional): a SQ formula used to evaluate the foreign key of the map key.

class (required): the entity class used as the map key.

If your table does not have an index column, and you still wish to use List as the property type, you can map the property as a Hibernate <bag>. A bag does not retain its order when it is retrieved from the database, but it can be optionally sorted or ordered.

6.2.4. Collections von Werten und "Many-to-Many"-Assoziationen

Any collection of values or many-to-many associations requires a dedicated collection table with a foreign key column or columns, collection element column or columns, and possibly an index column or columns.

formula (optional): an SQL formula used to evaluate the element foreign key value.

class (required): the name of the associated class.

fetch (optional - defaults to 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.

unique (optional): enables the DDL generation of a unique constraint for the foreign-key column. This makes the association multiplicity effectively one-to-many.

not-found (optional - defaults to exception): specifies how foreign keys that reference missing rows will be handled: ignore will treat a missing row as a null association.

entity-name (optional): the entity name of the associated class, as an alternative to class.

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.

not-found (optional - defaults to exception): specifies how cached identifiers that reference missing rows will be handled. ignore will treat a missing row as a null association.

entity-name (optional): the entity name of the associated class, as an alternative to class.

The <one-to-many> element does not need to declare any columns. Nor is it necessary to specify the table name anywhere.

Warnung

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 for more information.

The following 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:

If you want the database itself to order the collection elements, use the order-by attribute of set, bag or map mappings. This solution is only available under JDK 1.4 or higher and is implemented using LinkedHashSet or LinkedHashMap. This performs the ordering in the SQL query and not in the memory.

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 a many-to-many relationship in Javais created:

category.getItems().add(item);//The category now "knows" about the relationshipitem.getCategories().add(category);//The item now "knows" about the relationshipsession.persist(item);//The relationship won't be saved!session.persist(category);//The relationship will be saved

Mapping one end of an association with inverse="true" does not affect the operation of cascades as these are orthogonal concepts.

6.3.3. Bidirektionale Assoziationen mit indizierten 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 that maps to the index column you can use inverse="true" on the collection mapping:

If there is no such property on the child class, the association cannot be considered truly bidirectional. That is, there is information available at one end of the association that is not available at the other end. In this case, you cannot map the collection inverse="true". Instead, you could use the following mapping:

A second approach is to remodel the association as an entity class. This is the most common approach.

A final alternative is to use composite elements, which will be discussed later.

6.3.5. Using an <idbag>

The majority of the many-to-many associations and collections of values shown previously all map to tables with composite keys, even though it has been have suggested that entities should have synthetic identifiers (surrogate keys). A pure association table does not seem to benefit much from a surrogate key, although a collection of composite values might. It is for this reason that Hibernate provides a feature that allows you to map many-to-many associations and collections of values to a table with a surrogate key.

The <idbag> element lets you map a List (or Collection) with bag semantics. For example:

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, however, provide any mechanism for discovering the surrogate key value of a particular row.

The update performance of an <idbag> supersedes a regular <bag>. Hibernate can locate individual rows efficiently and update or delete them individually, similar to a list, map or set.