What is the difference between using a @OneToMany
and @ElementCollection
annotation since both work on the one-to-many relationship?

- 704
- 5
- 26

- 3,315
- 8
- 25
- 29
-
8In a nutshell, @ElementCollection is used when the existence of the child-entity is meaningless without the parent entity, IOW, whenever a parent entity is removed, your children will also be... – deldev Nov 18 '15 at 13:40
-
1I believe it is NOT the child Entity, it is Value Type/Value Object which is embedded and whose existence is meaning less without the main Entity in which it is contained. – CuriousMind Dec 22 '17 at 15:01
-
1agree with @CuriousMind, in JPA an 'Entity' has its own lifecycle. – mhrsalehi Jan 25 '20 at 05:07
8 Answers
ElementCollection
is a standard JPA annotation, which is now preferred over the proprietary Hibernate annotation CollectionOfElements
.
It means that the collection is not a collection of entities, but a collection of simple types (Strings, etc.) or a collection of embeddable elements (class annotated with @Embeddable
).
It also means that the elements are completely owned by the containing entities: they're modified when the entity is modified, deleted when the entity is deleted, etc. They can't have their own lifecycle.

- 21,644
- 19
- 100
- 126

- 678,734
- 91
- 1,224
- 1,255
I believe @ElementCollection
is mainly for mapping non-entities (embeddable or basic) while @OneToMany
is used to map entities. So which one to use depend on what you want to achieve.

- 35,493
- 19
- 190
- 259

- 4,803
- 2
- 17
- 27
-
1Thanks Peder for the answer! You've a valid point there since @OneToMany can only relate entities. – n_g Jan 23 '12 at 09:03
@ElementCollection
allows you to simplify code when you want to implement one-to-many relationship with simple or embedded type. For instance in JPA 1.0 when you wanted to have a one-to-many relationship to a list of String
s, you had to create a simple entity POJO (StringWrapper
) containing only primary key and the String
in question:
@OneToMany
private Collection<StringWrapper> strings;
//...
public class StringWrapper {
@Id
private int id;
private String string;
}
With JPA 2.0 you can simply write:
@ElementCollection
private Collection<String> strings;
Simpler, isn't it? Note that you can still control the table and column names using @CollectionTable
annotation.
See also:

- 334,321
- 69
- 703
- 674
Basic or Embedded: @ElementCollection
Entities: @OneToMany or @ManyToMany
@ElementCollection:
- the relation is managed (only) by the entity in which the relation is defined
- table contains id reference to the owning entity plus basic or embedded attributes
@OneToMany / @ManyToMany:
- can also be managed by the other entity
- join table or column(s) typically contains id references only

- 399
- 3
- 10
ElementCollection can 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.

- 71
- 1
- 5
@ElementCollection
This annotation will be applied when there is a relation with non-entity and these associations relation was HAS-A. Every collection is created with a table and gets relation by Foreign Key.
There are two types of element collections
- Index (List, Map)
- Non-Index (Set)
Index: The index type collection has a table with 3 columns they are
- Key Column (Foriegn Key)
- Index Column (Position of data in collection)
- Element Column (Data)
Non-Index: The Non-Index type collection has a table with 2 columns they are
- Key Column
- Element Column
Note: Here it won't have any index column because, Since a SET doesn’t retain the insertion order.
Multiplicity
This is a way to implement the HAS-A relation between two entities and the cardinality ratio depends on their relation.@ElementCollection
marks a collection. This does not necessarily mean that this collection references a 1-n join.

- 5,158
- 7
- 39
- 56
You can use ElementCollection replace for you use @OneToMany. Example you can have one Project in many versions.
@ElementCollection
@CollectionTable(name="versions",
joinColumns = @JoinColumn(name="projectID"))
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name="version",nullable = false)
private Set<String> versions;
You also can use @ElementCollection in mapping OGM for array in one collection.
@ElementCollection(fetch = FetchType.EAGER)
private Set<String> researchAreas;

- 74
- 5