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 should not 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 not 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() {..}