For a Hibernate @ManyToMany that represents unique membership without meaningful order, use a Set. It expresses that relationship directly and avoids some inefficient join-table updates associated with bag-style collections. Use a List when position matters—and persist that position explicitly.
Why a Set usually fits a many-to-many relationship
A many-to-many association usually represents membership: a student belongs to a course, or a user has a role. If a member should appear only once and the order is irrelevant, a Java Set matches the domain rule. For example:
@ManyToMany
private Set<Role> roles = new HashSet<>();
Hibernate maps collection types differently. A Set has set semantics. A List with list semantics is a list, while an untyped Collection is treated as a bag. Without persistent list-index semantics, a List or Collection association may be a bag: it can contain duplicates and has no defined order. Hibernate’s ORM User Guide describes this distinction; its 2025 guide also notes that a many-to-many represented as a Collection or List may contain duplicate elements because it is a bag, not a set.
How collection choice affects join-table updates
With a unidirectional many-to-many, Hibernate documents a removal strategy that may delete all link rows for a parent and then recreate the rows for the remaining members. That can make a seemingly small change produce more join-table work than expected. A set represents membership changes as additions and removals more naturally, though the SQL Hibernate emits depends on the mapping and version; choosing Set is not a guarantee of a particular SQL statement.
#1 Best Overall
Vlad Mihalcea’s Hypersistence Optimizer User Guide likewise recommends a Java Set over a List for many-to-many mappings because a bag may lead to inefficient SQL. The practical reason is to model the relationship correctly first, and avoid unnecessary link-table churn where the mapping permits it.
When a List is the right choice
Choose a List if order or position is part of the relationship’s meaning—for example, a ranked reading list or ordered workflow steps. A plain Java List does not make database row order durable. Persist the position with @OrderColumn, or represent the relationship as an explicit link entity with a position field. Do not rely on insertion order or assume a database returns rows in a stable order without an ordering rule.
Use a link entity when the relationship has its own data
If the association needs attributes such as rank, date added, quantity, or notes, the join is more than a bare connection. Model it as an entity rather than trying to attach those facts to a plain many-to-many. The link entity can carry those fields and make ordering or other relationship behavior explicit.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Keep entity equality and both sides consistent
A Set relies on equality and hash codes to recognize duplicates. Entity elements therefore need stable, well-considered equals and hashCode behavior; values used by a hash-based set should not change in a way that breaks set membership while the entity is in the collection.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
For a bidirectional association, update the owning side—the side that maps the join table—so Hibernate persists the change. Updating only the inverse collection does not write the join-table change. Helper methods can keep both in-memory collections synchronized while ensuring the owning side is updated.
Avoid cascading REMOVE across a many-to-many unless deleting a related entity is truly intended. Related entities are often shared by multiple parents, so removing one link should not accidentally delete an entity still used elsewhere.
Quick Recap
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

