Using Collections in Entity Fields and Properties
Collection-valued persistent fields and properties must use the supported Java collection
interfaces regardless of whether the entity uses persistent fields or properties. The following
collection interfaces may be used:
■ java.util.Collection
■ java.util.Set
Entities
Chapter 32 • Introduction to the Java Persistence API 585
■ java.util.List
■ java.util.Map
If the entity class uses persistent fields, the type in the preceding method signatures must be one
of these collection types. Generic variants of these collection types may also be used. For
example, if it has a persistent property that contains a set of phone numbers, the Customer
entity would have the following methods:
Set<PhoneNumber> getPhoneNumbers() { ... }
void setPhoneNumbers(Set<PhoneNumber>) { ... }
If a field or property of an entity consists of a collection of basic types or embeddable classes, use
the javax.persistence.ElementCollection annotation on the field or property.
The two attributes of @ElementCollection are targetClass and fetch. The targetClass
attribute specifies the class name of the basic or embeddable class and is optional if the field or
property is defined using Java programming language generics. The optional fetch attribute is
used to specify whether the collection should be retrieved lazily or eagerly, using the
javax.persistence.FetchType constants of either LAZY or EAGER, respectively. By default, the
collection will be fetched lazily.
The following entity, Person, has a persistent field, nicknames, which is a collection of String
classes that will be fetched eagerly. The targetClass element is not required, because it uses
generics to define the field.
@Entity
public class Person {
...
@ElementCollection(fetch=EAGER)
protected Set<String> nickname = new HashSet();
...
}
Collections of entity elements and relationships may be represented by java.util.Map
collections. A Map consists of a key and a value.
When using Map elements or relationships, the following rules apply.
■ The Map key or value may be a basic Java programming language type, an embeddable class,
or an entity.
■ When the Map value is an embeddable class or basic type, use the @ElementCollection
annotation.
■ When the Map value is an entity, use the @OneToMany or @ManyToMany annotation.
■ Use the Map type on only one side of a bidirectional relationship.
If the key type of a Map is a Java programming language basic type, use the annotation
javax.persistence.MapKeyColumn to set the column mapping for the key. By default, the name
Entities
586 The Java EE 6Tutorial • July 2012
attribute of @MapKeyColumn is of the form RELATIONSHIP-FIELD/PROPERTY-NAME_KEY.
For example, if the referencing relationship field name is image, the default name attribute is
IMAGE_KEY.
If the key type of a Map is an entity, use the javax.persistence.MapKeyJoinColumn annotation.
If the multiple columns are needed to set the mapping, use the annotation
javax.persistence.MapKeyJoinColumns to include multiple @MapKeyJoinColumn
annotations. If no @MapKeyJoinColumn is present, the mapping column name is by default set to
RELATIONSHIP-FIELD/PROPERTY-NAME_KEY. For example, if the relationship field name is
employee, the default name attribute is EMPLOYEE_KEY.
If Java programming language generic types are not used in the relationship field or property,
the key class must be explicitly set using the javax.persistence.MapKeyClass annotation.
If the Map key is the primary key or a persistent field or property of the entity that is the Map
value, use the javax.persistence.MapKey annotation. The @MapKeyClass and @MapKey
annotations cannot be used on the same field or property.
If the Map value is a Java programming language basic type or an embeddable class, it will be
mapped as a collection table in the underlying database. If generic types are not used, the
@ElementCollection annotation’s targetClass attribute must be set to the type of the Map
value.
If the Map value is an entity and part of a many-to-many or one-to-many unidirectional
relationship, it will be mapped as a join table in the underlying database. A unidirectional
one-to-many relationship that uses a Map may also be mapped using the @JoinColumn
annotation.
If the entity is part of a one-to-many/many-to-one bidirectional relationship, it will be mapped
in the table of the entity that represents the value of the Map. If generic types are not used, the
targetEntity attribute of the @OneToMany and @ManyToMany annotations must be set to the
type of the Map value.