Hibernate Associations and Collections

Collection Mapping in Hibernate

Learn how to map lists, sets, maps, bags, value collections, and entity relationships using Hibernate and JPA.

Collection Types Supported by Hibernate

A persistent class can contain a collection of values or entity references. Common Java collection types are:

  • List
  • Set
  • SortedSet
  • Map
  • SortedMap
  • Collection

Hibernate also supports custom collection semantics through its extension points. Prefer standard Java collections and JPA annotations for application code.

public class Question {
    private Long id;
    private String text;
    private List<String> answers;
}

Mapping a List of Basic Values

Use @ElementCollection when the collection contains values such as strings, numbers, or embeddable value objects rather than entities.

@Entity
public class Question {
    @Id
    @GeneratedValue
    private Long id;

    private String text;

    @ElementCollection
    @CollectionTable(
        name = "question_answer",
        joinColumns = @JoinColumn(name = "question_id")
    )
    @OrderColumn(name = "answer_position")
    @Column(name = "answer")
    private List<String> answers = new ArrayList<>();
}

@OrderColumn stores the list position. Without an order column, use a Set when order is not part of the data model.

Mapping a List of Entities

When a collection contains entity objects, use a relationship such as one-to-many or many-to-many. The following bidirectional mapping stores many answers for one question.

@Entity
public class Question {
    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(
        mappedBy = "question",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    @OrderBy("id ASC")
    private List<Answer> answers = new ArrayList<>();
}

@Entity
public class Answer {
    @Id
    @GeneratedValue
    private Long id;

    private String text;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "question_id", nullable = false)
    private Question question;
}

mappedBy identifies the owning field on Answer. Keep both sides synchronized in helper methods so the in-memory model and database relationship remain consistent.

Mapping a Collection in an XML Mapping File

Legacy Hibernate mapping files use <list>, <set>, <bag>, or <map> inside a <class> mapping.

<class name="com.example.Question" table="question">
  <id name="id" column="id">
    <generator class="identity"/>
  </id>
  <property name="text" column="question_text"/>

  <list name="answers" table="question_answer">
    <key column="question_id" not-null="true"/>
    <index column="answer_position"/>
    <element column="answer" type="string"/>
  </list>
</class>

The <key> stores the foreign key, <index> stores the list position, and <element> stores the basic value. For entity references, replace <element> with <one-to-many> or <many-to-many>.

Understanding the Key Element

The key column is the foreign key in the collection table. It points back to the identifier of the owning entity.

<key
  column="question_id"
  not-null="true"
  on-delete="cascade"
/>

Important legacy attributes include:

  • column: foreign-key column name.
  • not-null: prevents collection rows without an owner.
  • on-delete: controls database-level delete behavior where supported.
  • property-ref: references a property other than the owner's primary key.
  • unique: adds a uniqueness constraint when the relationship requires it.

Indexed and Non-Indexed Collections

Indexed

List and Map need an additional value that represents position or key. In XML this is commonly <index> or <index-many-to-many>.

Non-indexed

Set, Bag, and ordinary collections do not use a numeric position. A set relies on equality and hash code behavior to identify unique elements.

@ElementCollection
@MapKeyColumn(name = "answer_type")
private Map<String, String> answersByType = new HashMap<>();

Collection Element Types

MappingUse it forModern annotation
Basic elementStrings, numbers, dates, and other basic values.@ElementCollection
Component elementEmbeddable value objects such as addresses.@ElementCollection with @Embeddable
One-to-manyMany child entities belong to one parent.@OneToMany
Many-to-manyMultiple entities on both sides share a relationship.@ManyToMany
Performance note: collections are commonly lazy, but accessing them outside an open persistence context can cause LazyInitializationException. Fetch only the data required by the use case.

Collection Mapping Best Practices

  • Initialize collection fields to an empty collection instead of null.
  • Use Set only when equality and uniqueness are well defined.
  • Use List with an explicit order column when position is meaningful.
  • Use Map when a stable key makes lookup clearer than scanning a list.
  • Use cascade and orphan removal only when the child lifecycle truly belongs to the parent.
  • Avoid eager collection fetching for large relationships.
  • Do not include lazy collections in equals() or hashCode().
  • Use migrations to create collection tables and foreign-key constraints in production.
Next topics: mapping List, mapping Bag, mapping Set, mapping Map, one-to-many collections, and many-to-many collections.