liveBook · Manning

One-to-many relationship

As explained in Java Persistence with Spring Data and Hibernate epub

A many-to-one association is an association in which multiple instances on one side may reference a single instance on the other side.

A one-to-many relationship links one entity to multiple entities of another type. One Item can have many Bids; from each Bid back to its Item, the same relationship is many-to-one. In Java, the Item can hold a collection of Bid references while each Bid holds an Item reference. In a relational schema, an ITEM_ID foreign key on BID records the link. Java references are directional, so navigation in both directions requires both properties; SQL can instead retrieve either view with a join. section 1.2.4 section 3.2.4 section 9.4.1

Keep both Java sides consistent when creating a bidirectional link. Adding a Bid to Item.bids alone does not set Bid.item. A convenience method can reject null or previously assigned bids, then add the bid and set its Item. Initialize a collection such as Set<Bid> with an empty HashSet, but declare the mapped property using a collection interface. section 3.2.4

Listing 3.3 A convenience method simplifies relationship management
Path: Ch03/domainmodel/src/main/java/com/manning/javapersistence/ch03/ex03
 /Item.java
 
public void addBid(Bid bid) {
    if (bid == null)
        throw new NullPointerException("Can't add null Bid");
    if (bid.getItem() != null)
        throw new IllegalStateException(
                    "Bid is already assigned to an Item");
    bids.add(bid);
    bid.setItem(this);
}

The addBid method updates both references and guards against invalid assignments. section 3.2.4

For a bidirectional JPA mapping, Item.bids can use @OneToMany(mappedBy = "item") while Bid.item supplies the corresponding many-to-one property. Iterating the collection can trigger a query for Bids with the Item’s foreign key. The collection also permits selected state changes to cascade from Item to its Bids. Neither convenience is free: mapping a collection adds Java code and complicates relationship management. If collection iteration is uncommon, an explicit query may be simpler. section 8.3.2 section 9.2

Listing 8.17 Item has a collection of Bid references
Path: Ch08/mapping-associations/src/main/java/com/manning/javapersistence
 /ch08/onetomany/bidirectional/Item.java
 
@Entity
public class Item {
    // . . .
 
    @OneToMany(mappedBy = "item",                #1
               fetch = FetchType.LAZY)           #2
    private Set<Bid> bids = new HashSet<>();
    //  . . .
}
#1 The <kbd>@OneToMany</kbd> annotation is required to make the association bidirectional. In this case, we also have to set the <kbd>mappedBy</kbd> parameter.
#2 The argument is the name of the property on the “other side.” The fetching will be <kbd>LAZY</kbd> by default.

The Item mapping shows an initialized Set and the @OneToMany mappedBy property used for bidirectional navigation. section 8.3.2

Choose the collection representation and lifecycle behavior to match the work being done:

  • Use a Set when duplicates are disallowed. A Map can instead key each Bid by its identifier with @MapKey(name = "id"); the BID table still uses ITEM_ID, and the chosen map-key property must be unique. section 3.2.4 section 9.4.1
  • Select cascades deliberately. With PERSIST and REFRESH on a User-to-BillingDetails collection, persisting added details is simpler, but refreshing the User can issue a SELECT for each managed detail and then load the collection again. section 13.1.3
  • Use Spring Data JDBC’s @MappedCollection(idColumn = "USER_ID") for a User.addresses set backed by ADDRESSES.USER_ID. A repository count by that column needs an explicit @Query when userId is not a property of Address. section 15.3.3

Do not add a collection merely because the database permits one-to-many links. Prefer the simpler many-to-one side or an explicit query when direct iteration is not useful; more elaborate collection mappings can make storage, updates, and deletion harder. section 9.2 section 9.5

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Works through Java reference integrity, JPA mapping and cascades, collection alternatives, and a Spring Data JDBC foreign-key mapping.
Examples
Uses Item–Bid sets and maps, User–BillingDetails refresh, and a User–Address schema with a repository query.
What it assumes
Assumes Java classes and collections; explains how object references correspond to relational foreign keys.
What you can do after
Build it from scratch with synchronized Java references, or apply it via JPA or Spring Data JDBC mappings.
How it connects
Connects many-to-one associations, foreign keys, bidirectional navigation, collection mappings, cascading, and explicit queries.

Also explained in

Compare how 12 books explain one-to-many relationship →

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.