Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 23 di 68
  • livello ninja
Indice lezioni

JPA: relazioni OneToMany, ManyToOne e ManyToMany

Come definire relazioni uno a molti, molti a uno e molti a molti tra Entity con la Java Persistence API.
Come definire relazioni uno a molti, molti a uno e molti a molti tra Entity con la Java Persistence API.
Link copiato negli appunti

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:

Figura 1. Relazione uno a molti unidirezionale.
Relazione uno a molti unidirezionale

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:

Figura 2. Relazione molti a molti unidirezionale
Relazione molti a molti unidirezionale

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.

Ti consigliamo anche