Chapter 8. Advanced entity association mappings

 

In this chapter

  • Mapping one-to-one entity associations
  • One-to-many mapping options
  • Many-to-many and ternary entity relationships

In the previous chapter, we demonstrated a unidirectional many-to-one association, made it bidirectional, and finally enabled transitive state changes with cascading options. One reason we discuss more advanced entity mappings in a separate chapter is that we consider quite a few of them rare, or at least optional. It’s possible to only use component mappings and many-to-one (occasionally one-to-one) entity associations. You can write a sophisticated application without ever mapping a collection! We’ve shown the particular benefits you gain from collection mappings in the previous chapter; the rules for when a collection mapping is appropriate also apply to all examples in this chapter. Always make sure you actually need a collection before you attempt a complex collection mapping.

Let’s start with mappings that don’t involve collections: one-to-one entity -associations.

Major new features in JPA 2
  • Many-to-one and one-to-one associations may now be mapped with an intermediate join/link table.
  • Embeddable component classes may have unidirectional associations to entities, even many-valued with collections.

8.1. One-to-one associations

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/sharedprimarykey/Address.java

@Entity
public class Address {
<enter/>
    @Id
    @GeneratedValue(generator = Constants.ID_GENERATOR)
    protected Long id;
<enter/>
    @NotNull
    protected String street;
<enter/>
    @NotNull
    protected String zipcode;
<enter/>
    @NotNull
    protected String city;
<enter/>
    // ...
}

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/sharedprimarykey/User.java

Path: /examples/src/test/java/org/jpwh/test/associations/OneToOneSharedPrimaryKey.java

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/foreigngenerator/User.java

@Entity
@Table(name = "USERS")
public class User {
<enter/>
    @Id
    @GeneratedValue(generator = Constants.ID_GENERATOR)
    protected Long id;
<enter/>
    @OneToOne(
        mappedBy = "user",
        cascade = CascadeType.PERSIST
    )
    protected Address shippingAddress;
    // ...
}

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/foreigngenerator/Address.java

Path: /examples/src/test/java/org/jpwh/test/associations/OneToOneForeignGenerator.java

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/foreignkey/User.java

Path: /examples/src/test/java/org/jpwh/test/associations/OneToOneForeignKey.java

Path: /model/src/main/java/org/jpwh/model/associations/onetoone/jointable/Shipment.java

Path: /examples/src/test/java/org/jpwh/test/associations/OneToOneJoinTable.java

Shipment someShipment = new Shipment();
em.persist(someShipment);
<enter/>
Item someItem = new Item("Some Item");
em.persist(someItem);
<enter/>
Shipment auctionShipment = new Shipment(someItem);
em.persist(auctionShipment);

8.2. One-to-many associations

Path: /model/src/main/java/org/jpwh/model/associations/onetomany/bag/Item.java

@Entity
public class Item {
<enter/>
    @OneToMany(mappedBy = "item")
    public Collection<Bid> bids = new ArrayList<>();
<enter/>
    // ...
}

Path: /examples/src/test/java/org/jpwh/test/associations/OneToManyBag.java

sitemap