OneToMany e ManyToOne
Passiamo adesso alla relazione uno a molti partendo dal caso unidirezionale. Questo tipo di relazione si modella in genere
con una foreign key da una tabella ad un altra in modo tale che diversi record di una tabella possano referenziare uno stesso
record dell'altra. Nel nostro caso abbiamo un cliente che può effettuare più prenotazioni.
La tabella Booking
conterrà quindi diversi record che punteranno ad un record della tabella Customer
relativo al cliente che le ha effettuate:
Abbiamo quindi la tabella Booking
con la colonna CUSTOMER_ID
sulla quale è applicata una foreign key verso la chiave primaria ID
della
tabella Customer
. Per realizzare questa relazione facciamo uso dell'annotation @OneToMany
all'interno dell'entity Customer
:
private List<Booking> bookings;
@OneToMany
@JoinColumn(name="CUSTOMER_ID")
public List<Booking> getBookings() {
return bookings;
}
public void setBookings(List<Booking> bookings) {
this.bookings = bookings;
}
Anche in questo caso utilizziamo @JoinColumn
per specificare la colonna che detiene la foreign key. Per ottenere una relazione
bidirezionale dobbiamo prima di tutto aggiornare la @OneToMany
lato Customer
:
@OneToMany(mappedBy="customer")
public List<Booking> getBookings() {
return bookings;
}
Ed aggiungere lato Booking l'annotation @ManyToOne
su un campo di riferimento verso Customer
:
@ManyToOne
@JoinColumn(name="CUSTOMER_ID")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
L'Owner della relazione è quindi l'entity Booking
(la tabella sottostante detiene la foreign key). @ManyToOne
è sempre Owner di una relazione e non ammette quindi mappedBy
.
ManyToMany
Concludiamo la trattazione
delle relazioni con l'ultimo tipo di relazione: molti a molti. Abbiamo questo tipo di relazione, ad esempio, tra l'entity Customer
e
l'entity Event
. Un cliente può partecipare a diversi eventi e un singolo evento coinvolgere diversi clienti. Lo schema relazionale
per questo tipo di relazione coinvolge una terza tabella di Join:
La tabella di join contiene due foreign key che puntano alle chiavi primarie delle tabelle Customer
ed event
. Una relazione di questo tipo si modella in JPA utilizzando l'annotation @ManyToMany
. Realizziamo l'entity Event
come fatto precedentemente per le altre Entity:
@Entity
@Table(name="EVENT")
@SequenceGenerator(name="EVENT_GENERATOR",sequenceName="EVENT_SEQUENCE")
public class Event {
private long id;
private String name;
private Date eventDate;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="EVENT_GENERATOR")
@Column(name="ID")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name="NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="EVENT_DATE")
@Temporal(TemporalType.DATE)
public Date getEventDate() {
return eventDate;
}
public void setEventDate(Date eventDate) {
this.eventDate = eventDate;
}
}
Ed aggiorniamo l'entity Customer
come segue:
private List<Event> events;
@ManyToMany
@JoinTable(name="EVENT_CUSTOMER",
joinColumns={@JoinColumn(name="CUSTOMER_ID")},
inverseJoinColumns={@JoinColumn(name="EVENT_ID")})
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
Nell'annotation specifichiamo il nome della tabella di join ed i nomi delle sue colonne che, per default, si assume
abbiano dei vincoli di foreign key verso le chiavi primarie delle due tabelle. La versione bidirezionale si ottiene facilmente
come negli altri casi utilizzando l'annotation @ManyToMany
con attributo mappedBy
sul lato opposto della relazione.