Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/Examples/JPA/2.0/ElementCollections

How to map collections of Basic or Emeddable values using an ElementCollection mapping

JPA 2.0 defines an ElementCollection mapping. It is meant to handle several non-standard relationship mappings. An ElementCollection can be used to define a one-to-many relationship to an Embeddable object, or a Basic value (such as a collection of Strings). An ElementCollection can also be used in combination with a Map column to define relationships were the key can be any type of object, and the value is an Embeddable object or a Basic value.

In JPA a ElementCollection relationship is defined through the @ElementCollection annotation or the <element-collection> element.

The ElementCollection values are always stored in a separate table. The table is defined through the @CollectionTable annotation or the <collection-table> element. The CollectionTable defines the table's name and @JoinColumn or @JoinColumns if a composite primary key.

Emdedded Collections

An ElementCollection mapping can be used to define a collection of Embeddable objects. This is not a typical usage of Embeddable objects as the objects are not embedded in the source object's table, but stored in a separate collection table. This is similar to a OneToMany, except the target object is an Embeddable instead of an Entity. This allows collections of simple objects to be easily defined, without requiring the simple objects to define an Id or ManyToOne inverse mapping. ElementCollection can also override the mappings, or table for their collection, so you can have multiple entities reference the same Embeddable class, but have each store their dependent objects in a separate table.

The limitations of using an ElementCollection instead of a OneToMany is that the target objects cannot be queried, persisted, merged independently of their parent object. They are strictly privately-owned (dependent) objects, the same as an Embedded mapping. Their is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent. ElementCollection still can use a fetch type and defaults to LAZY the same as other collection mappings.

Example of an ElementCollection relationship database

EMPLOYEE (table)

EMP_ID F_NAME L_NAME SALARY
1 Bob Way 50000
2 Joe Smith 35000

PHONE (table)

OWNER_ID TYPE AREA_CODE P_NUMER
1 home 613 792-0001
1 work 613 494-1234
2 work 416 892-0005

Example of an ElementCollection relationship annotations

@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  private List<Phone> phones;
  ...
}
@Embeddable
public class Phone {
  private String type;
  private String areaCode;
  @Column(name="P_NUMBER")
  private String number;
  ...
}

Example of an ElementCollection relationship XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID"/>
        </id>
        <element-collection name="phones">
            <collection-table name="PHONE">
                <join-column name="OWNER_ID"/>
            </collection-table>
        </element-collection>
    </attributes>
</entity>
<embeddable name="Phone" class="org.acme.Phone" access="FIELD">
    <attributes>
        <basic name="number">
            <column name="P_NUMBER"/>
        </basic>
    </attributes>
</embeddable>

Basic Collections

An ElementCollection mapping can be used to define a collection of Basic objects. The Basic values are stored in a separate collection table. This is similar to a OneToMany, except the target is a Basic value instead of an Entity. This allows collections of simple values to be easily defined, without requiring defining a class for the value.

Their is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent. ElementCollection still can use a fetch type and defaults to LAZY the same as other collection mappings.

Example of an ElementCollection relationship to a basic value database

EMPLOYEE (table)

EMP_ID F_NAME L_NAME SALARY
1 Bob Way 50000
2 Joe Smith 35000

PHONE (table)

OWNER_ID PHONE_NUMBER
1 613-792-0001
1 613-494-1234
2 416-892-0005

Example of a ElementCollection relationship to a basic value annotations

@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  @Column(name="PHONE_NUMBER")
  private List<String> phones;
  ...
}

Example of a ElementCollection relationship to a basic value XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID"/>
        </id>
        <element-collection name="phones">
            <column name="PHONE_NUMBER"/>
            <collection-table name="PHONE">
                <join-column name="OWNER_ID"/>
            </collection-table>
        </element-collection>
    </attributes>
</entity>

Back to the top