Le sfumature del metodo merge()

Se desideri utilizzare Hibernate per modificare un oggetto che è già stato memorizzato nel database, esistono anche diversi metodi per farlo.

Il primo è il metodo merge() , che aggiorna le informazioni nel database in base all'oggetto passato . Questo richiamerà la query SQL UPDATE. Esempio:

User user = new User();
user.setName("Kolyan");
session.save(user);

session.evict(user);     // detach the object from the session
user.setName("Masha");

User user2 = (User) session.merge(user);

Ci sono molte sfumature importanti qui.

Innanzitutto, il metodo merge() restituisce il risultato, l'oggetto aggiornato. Questo oggetto ha uno stato Persist ed è collegato all'oggetto sessione. L'oggetto passato al metodo merge() non cambia.

Può sembrare che non ci sia differenza tra utente e utente2, ma non lo è. È possibile passare un oggetto POJO al metodo merge() e, di conseguenza, il metodo può restituire un proxy (a seconda delle impostazioni di Hibernate). Quindi ricorda solo che il metodo merge() non cambia l'oggetto passato.

In secondo luogo, se l'oggetto passato a merge() ha lo stato Transient (e non ha un ID), verrà creata una riga separata per esso nel database. In altre parole, verrà eseguito il comando persist() .

In terzo luogo, se un oggetto già collegato alla sessione (con lo stato Persist) viene passato al metodo merge() , non accadrà nulla: il metodo restituirà semplicemente lo stesso oggetto. Perché? E tutto perché quando viene eseguita la transazione, i dati verranno comunque scritti nel database:

User user = new User();
user.setName("Kolyan");
session.save(user);

user.setName("Masha"); //change the object attached to the session

session.close();  //all changed objects will be written to the database

Non è necessario salvare l'oggetto ogni volta dopo le sue modifiche. Se questo oggetto è nello stato Persist, Hibernate farà tutto da solo. Se modifichi un oggetto che è "attaccato alla base", tutte le sue modifiche verranno scritte sulla base.

Le sfumature del metodo update()

Hibernate ha anche un metodo update() , che, come il metodo save() , è stato ereditato dalle versioni precedenti. Con questo metodo è possibile aggiornare solo i dati di un oggetto già salvato. Questo richiamerà la query SQL UPDATE. Esempio:

User user = new User();
user.setName("Kolyan");
session.save(user);

session.evict(user);     // detach the object from the session
user.setName("Masha");

session.update(user);

Questo metodo non restituisce nulla e non modifica l'oggetto esistente.

Se chiami questo metodo su un nuovo oggetto, verrà semplicemente generata un'eccezione:

User user = new User();
user.setName("Kolyan");
session.update(user);   //an exception will be thrown here

metodo saveOrUpdate()

Prima dell'avvento di JPA, la funzione del metodo persist() veniva eseguita dal metodo saveOrUpdate() . Il suo compito era aggiornare le informazioni sull'oggetto esistente nel database e, se non ce ne sono, crearlo. Viene quasi sempre utilizzato al posto dei metodi save() e update() .

A differenza del metodo update() , può modificare l'oggetto che gli viene passato. Ad esempio, impostalo sull'ID assegnato durante il salvataggio nel database. Esempio:

User user = new User();
user.setName("Kolyan");
session.saveOrUpdate(user);   //object will be written to the database

Come funziona:

  • se l'oggetto passato ha un ID, viene chiamato il metodo UPDATE SQL
  • se l'ID dell'oggetto passato non è impostato, viene chiamato il metodo INSERT SQL