ManyToMany relationships with Java Persistence (JSR-220)

The scenario is as following: each table can have many reservations, and each reservation can span many tables. Here is our first trial:

// Table.java
@ManyToMany(
  targetEntity=Reservation.class
)
public List getReservations() {..}

// Reservation.java
@ManyToMany(
  targetEntity=Table.class
)
public List getTables() {..}

We end up with linktables tables_reservations and reservations_tables. This is not what we want. It shouldn’t be possible to remove a table when there are still reservations related to that table. We change our code so that table becomes the owner of the relationship.

// Table.java
@ManyToMany(
  targetEntity=Reservation.class, 
  mappedBy="tables"
)
public List getReservations() {..}

Allright, now we only have the linktable reservations_tables. Exactly the same as we experienced with OneToMany relationships the cascading persist works when we persist a child (reservation). If we want the cascading persist to work when we persist a parent (table) we have to make sure that the child (reservation) has the parent set. An important difference is that we can’t enforce this thus i advise not to use the cascade attribute on the owner (table).

// Table.java
@ManyToMany(
  targetEntity=Reservation.class,
  mappedBy="tables"
) 
public List getReservations() {..}

// Reservation.java
@ManyToMany(
  targetEntity=Table.class, 
  cascade=CascadeType.PERSIST
)
public List getTables() {..}

We decide to use the Hibernate Validator classes to enforce that a reservation is associated with at least one table. For some reason the SizeValidator returns true if the value is null thus we also add a NotNullValidator:

// Reservation.java
import org.hibernate.validator.*;
@ManyToMany(
  targetEntity=Table.class,
  cascade=CascadeType.PERSIST
)
@NotNull 
@Size(min=1) 
public List getTables() { .. }

Ok, this allows us to enforce that reservations are always associated with at least one table. We decide to allow cascading persist on the parent.

@ManyToMany(
  targetEntity=Reservation.class, 
  mappedBy="tables", 
  cascade=CascadeType.PERSIST
)
public List getReservations() {..}

This entry was posted on Saturday, January 28th, 2006 at 02:27 and is filed under Hibernate. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

Comments are closed.