In questo capitolo continuiamo il discorso sulla propagazione
delle operazioni di persistenza ad entity relazionate
con quella oggetto della persistenza stessa.
Se ad esempio volessimo propagare l'operazione persist()
da Booking
a Customer
, dovremmo modificare la relazione @ManyToOne
su Booking
con:
..
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="\"CUSTOMER_ID\"")
public Customer getCustomer() {
return customer;
}
..
Sull'attributo cascade
possiamo specificare CascadeType.MERGE
, CascadeType.REFRESH
, CascadeType.REMOVE
, un insieme di queste opzioni
o tutte le opzioni con CascadeType.ALL
, riuscendo quindi a propagare le operazioni di persistenza necessarie in base
ai requisiti di progettazione.
Con il cascade impostato, il codice del metodo necessario per la persistenza di Booking
e, allo stesso tempo di Customer
, sarebbe più semplicemente:
..
@Override
public void firstBooking(Customer customer, Booking booking, Room room) {
booking.setCustomer(customer);
booking.setRoom(room);
entityManager.persist(booking);
}
..
Per testarlo definiamo nella classe di test dei nuovi metodi:
..
@Test
public void testAddNewRoom() throws NamingException{
roomServiceRemote = (RoomServiceRemote)namingContext.lookup(ROOM_REMOTE_JNDI_NAME);
Room room = new Room();
room.setFree("yes");
room.setNum(1);
room.setType("Single");
roomServiceRemote.addRoom(room);
}
@Test
public void testFirstBooking() throws NamingException{
customerServiceRemote = (CustomerServiceRemote)namingContext.lookup(CUSTOMER_REMOTE_JNDI_NAME);
roomServiceRemote = (RoomServiceRemote)namingContext.lookup(ROOM_REMOTE_JNDI_NAME);
Customer customer = new Customer();
customer.setFirstName("Luigi");
customer.setLastName("Bianchi");
Room room = roomServiceRemote.findById(50);
Booking booking = new Booking();
booking.setAmount(300);
booking.setCheckIn(new Date());
booking.setCheckOut(new Date());
customerServiceRemote.firstBooking(customer, booking, room);
}
..
Il primo metodo ci consente di inserire dei dati nella tabelle Room
, leggiamo quindi manualmente dal database gli id generati
da utilizzare nel metodo di testFirstBooking()
. Abbiamo definito un session bean stateless per la gestione dell'entity Room
come
fatto per Customer
.
Un altro aspetto estremamente importante è l'aggiornamento della relazione. Rimuoviamo il cascade inserito
in Booking
e immaginiamo di seguire il lato
inverso della relazione (in precedenza siamo partiti dal lato owner Booking) persistendo prima l'oggetto booking
e poi quello customer
:
..
@Override
public void firstBooking(Customer customer, Booking booking, Room room) {
booking.setRoom(room);
entityManager.persist(booking);
if(customer.getBookings()==null) customer.setBookings(new ArrayList<Booking>());
customer.getBookings().add(booking);
entityManager.persist(customer);
}
..
Il risultato che si ottiene è l'inserimento di un record in CUSTOMER
, uno in BOOKING
ma con foreign-key
verso CUSTOMER
a null
. Questo esempio dimostra quanto introdotto nei capitoli precedenti: l'aggiornamento
di una relazione avviene soltanto percorrendola dal lato owner al lato inverso.