liveBook · Manning

Map

As explained in Java Persistence with Spring Data and Hibernate epub

Map is a Java collection interface representing key-value associations in which each key maps to at most one value.

A Java Map associates each key with at most one value. In a persistent domain model, that makes it useful when an entity’s collection is naturally addressed by a name or another unique key. Declare the property with the Map interface, give it generic key and value types, and initialize it immediately with an implementation such as HashMap. Hibernate may wrap or replace that collection to support lazy loading and dirty checking. section 8.1.3 section 8.1.7

Listing 8.6 Persistent map storing its key and value pairs
Path: Ch08/mapping-collections/src/main/java/com/manning/javapersistence
 /ch08/mapofstrings/Item.java
 
@Entity
public class Item {
    // . . .
 
    @ElementCollection
    @CollectionTable(name = "IMAGE")
    @MapKeyColumn(name = "FILENAME")                          #1
    @Column(name = "IMAGENAME")                               #2
    private Map<String, String> images = new HashMap<>();
#1 Each map entry is a key/value pair. Here the key is mapped with <kbd>@MapKeyColumn</kbd> to <kbd>FILENAME</kbd>.
#2 The value is the <kbd>IMAGENAME</kbd> column. This means the user can only use a file once because a <kbd>Map</kbd> doesn’t allow duplicate keys.

A map of strings stores each image’s filename as the key and its user-supplied name as the value. @ElementCollection and @CollectionTable select the collection table; @MapKeyColumn and @Column identify its key and value columns. The table’s primary key combines the owning item’s ID with the filename, so a filename cannot be used twice for that item. section 8.1.7

Choose key and value mappings according to what the application needs to identify:

  • For a basic key, @MapKeyColumn names its column. Basic keys can be types other than String; enum keys use @MapKeyEnumerated, and temporal keys use @MapKeyTemporal. section 8.1.7
  • For an embeddable value, keep the key column separate from the value’s mapped fields. A Map<String, Image> can use a title as its key while Image holds the filename and dimensions; the filename can then be nullable because it is not part of the primary key. section 8.2.4
  • For an embeddable key, its mapped columns become part of the collection table’s composite primary key and cannot be nullable. Implement equals() and hashCode() so keys are unique within the map. @MapKeyColumn does not configure an embeddable key. section 8.2.5
Path: maps-ternary/src/main/java/com/manning/javapersistence
 /ch09/maps/ternary/Category.java
 
@Entity
public class Category {
    // . . .
    @ManyToMany(cascade = CascadeType.PERSIST)
    @MapKeyJoinColumn(name = "ITEM_ID")           #1
    @JoinTable(
        name = "CATEGORY_ITEM",
        joinColumns = @JoinColumn(name = "CATEGORY_ID"),
        inverseJoinColumns = @JoinColumn(name = "USER_ID")
    )
    private Map<Item, User> itemAddedBy = new HashMap<>();
    //  . . .
}
#1 The <kbd>@MapKeyJoinColumn</kbd> is optional; Hibernate or Spring Data JPA using Hibernate will default to the column name <kbd>ITEMADDEDBY_KEY</kbd> for the join/foreign key column referencing the <kbd>ITEM</kbd> table.

Maps can also hold entity references. Here an owning category maps each item key to the user who added it. @MapKeyJoinColumn identifies the item foreign key, while @JoinTable maps the three-column link table. The relationship has a compact Map API, but a link that later needs extra data may require a different model and application-code changes. section 9.4.2

Use a Map when lookup by a unique key expresses the relationship itself—not merely to avoid a separate link class. Unlike a List, it does not preserve positions through an index column. Decide whether the key is a basic value, an embeddable value, or an entity reference before choosing its mapping annotations and table key. section 8.1.6 section 9.4.2

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Works through annotation mappings, composite keys, embeddable keys and values, and a ternary join table.
Examples
Illustrates filename-to-name image entries, embeddable image values, and an item-to-user map owned by a category.
What it assumes
Assumes familiarity with Java collection interfaces and entity properties while demonstrating their persistent mappings.
What you can do after
Build it from scratch with JPA map annotations, selecting keys and columns to fit a value collection or entity association.
How it connects
Connects Map to element collections, embeddable types, composite primary keys, many-to-many associations, and join tables.

Also explained in

Compare how 42 books explain Map →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Java Persistence with Spring Data and Hibernate epub. The section links point to the parts of the book it draws on.