A collection table stores the elements of a persistent collection separately from its owning entity. Each row includes a foreign-key column referencing the owner, plus columns for the element, map key, or embedded value. section 8.2.6 section 8.2.2
In JPA, @ElementCollection identifies the persistent collection. @CollectionTable customizes the table name and join column; otherwise, provider defaults apply. A collection of strings can therefore map to CONTACT(USER_ID, NAME), while an image collection can map to IMAGE with an ITEM_ID owner key. section 8.2.2 section 8.2.6
The collection type determines additional columns and key constraints:
- A Set uses the owner key and non-nullable element columns as a composite primary key, preventing duplicate values. section 8.2.2 section 8.2.6
- A Map adds a key column; its primary key combines the owner key with that map key. @MapKeyColumn names the key column. section 8.2.4 section 8.1.7
- A list, bag, or map can replace a Set for basic values, while embeddable values can provide multiple mapped columns. section 8.2.6
Schema constraints must agree with Java equality. For a Set of embeddables, non-nullable columns participate in the composite key, so value types should implement equals() and hashCode() by value. Use @Column(nullable = false) when a column must receive a database NOT NULL constraint; @NotNull alone may not generate it. section 8.2.1
Mapping a set of embeddable images
An Item can declare @ElementCollection, @CollectionTable(name = "IMAGE"), and @AttributeOverride to map Set<Image> to a named table and column. @OrderBy("filename DESC, width DESC") provides load-time ordering when a LinkedHashSet is used. section 8.2.2
Listing 8.14 A Set of embeddable components with an override
Path: Ch08/mapping-collections/src/main/java/com/manning/javapersistence, /ch08/setofembeddables/Item.java @Entity public class Item { // . . . @ElementCollection #1 @CollectionTable(name = "IMAGE") #2 @AttributeOverride( name = "filename", column = @Column(name = "FNAME", nullable = false) ) private Set<Image> images = new HashSet<>(); #1 As before, the <kbd>@ElementCollection</kbd> annotation is required. Hibernate automatically knows that the target of the collection is an <kbd>@Embeddable</kbd> type from the declaration of a generic collection. #2 The <kbd>@CollectionTable</kbd> annotation overrides the default name for the collection table, which would have been <kbd>ITEM_IMAGES</kbd>.
Shows the complete entity-side mapping for a Set of embeddable components, including table and column overrides. section 8.2.2
