Qual è la differenza tra persist () e merge () in Hibernate?

Qual è la differenza tra persist () e merge () in Hibernate?

persist() può creare una query UPDATE & INSERT, ad esempio:

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); A a=new A(); session.persist(a); a.setName("Mario"); session.flush(); 

in questo caso la query verrà generata in questo modo:

 Hibernate: insert into A (NAME, ID) values (?, ?) Hibernate: update A set NAME=? where ID=? 

il metodo so persist() può generare un inserimento e un aggiornamento.

Ora con merge() :

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); Singer singer = new Singer(); singer.setName("Luciano Pavarotti"); session.merge(singer); session.flush(); 

Questo è ciò che vedo nel database:

 SINGER_ID SINGER_NAME 1 Ricky Martin 2 Madonna 3 Elvis Presley 4 Luciano Pavarotti 

Ora aggiorna un record usando l’ merge()

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); Singer singer = new Singer(); singer.setId(2); singer.setName("Luciano Pavarotti"); session.merge(singer); session.flush(); 

Questo è ciò che vedo nel database:

 SINGER_ID SINGER_NAME 1 Ricky Martin 2 Luciano Pavarotti 3 Elvis Presley 

Le specifiche JPA contengono una descrizione molto precisa della semantica di queste operazioni, meglio che in javadoc:

La semantica dell’operazione persist , applicata a un’ quadro X è la seguente:

  • Se X è una nuova entity framework, diventa gestita. L’ quadro X verrà inserita nel database al momento o prima del commit della transazione o come risultato dell’operazione di flush.

  • Se X è un’entity framework gestita preesistente, viene ignorata dall’operazione persist. Tuttavia, l’operazione persist viene collegata in cascata alle entity framework a cui fa riferimento X, se le relazioni da X a queste altre quadro sono annotate con il valore di elemento cascade=PERSIST o cascade=ALL o specificato con l’elemento descrittore XML equivalente.

  • Se X è un’ quadro rimossa, diventa gestita.

  • Se X è un object staccato, EntityExistsException può essere lanciato quando viene richiamata l’operazione persist, oppure EntityExistsException o un’altra PersistenceException può essere lanciata al momento del flush o del commit.

  • Per tutte le entity framework Y referenziate da una relazione da X, se la relazione con Y è stata annotata con il valore dell’elemento cascade cascade=PERSIST o cascade=ALL , l’operazione persist viene applicata a Y.


La semantica dell’operazione di unione applicata a un’ quadro X è la seguente:

  • Se X è un’entity framework distaccata, lo stato di X viene copiato su un’istanza di quadro gestita preesistente X ‘della stessa identity framework o viene creata una nuova copia gestita X’ di X.

  • Se X è una nuova istanza di entity framework, viene creata una nuova istanza di quadro gestita X ‘e lo stato di X viene copiato nella nuova istanza di quadro gestita X’.

  • Se X è un’istanza quadro rimossa, IllegalArgumentException verrà generata dall’operazione di unione (o il commit della transazione avrà esito negativo).

  • Se X è un’ quadro gestita, viene ignorata dall’operazione di unione, tuttavia, l’operazione di unione viene collegata in cascata alle quadro a cui fa riferimento le relazioni da X se queste relazioni sono state annotate con l’espressione cascade=MERGE value cascade=MERGE o cascade=ALL annotation.

  • Per tutte le quadro Y referenziate da relazioni da X aventi il ​​valore dell’elemento cascade cascade=MERGE o cascade=ALL , Y viene unito in modo ricorsivo come Y ‘. Per tutti questi Y a cui fa riferimento X, X ‘è impostato per fare riferimento a Y’. (Nota che se X è gestito allora X è lo stesso object di X ‘.)

  • Se X è un’ quadro unita a X ‘, con un riferimento a un’altra quadro Y, dove cascade=MERGE o cascade=ALL non è specificato, allora la navigazione della stessa associazione da X’ produce un riferimento a un object gestito Y ‘con il stessa id quadro persistente di Y.

Questo viene dall’APP. In un modo molto semplice:

persist (entity) dovrebbe essere usato con entity framework totalmente nuove, per aggiungerle al DB (se l’entity framework esiste già nel DB ci sarà il lancio di EntityExistsException).

Unire ( quadro) dovrebbe essere usato, per rimettere l’ quadro nel contesto di persistenza se l’ quadro è stata staccata e modificata.

Persist dovrebbe essere chiamato solo su nuove quadro, mentre l’unione è intesa per riattaccare quadro distaccate.

Se si sta utilizzando il generatore assegnato, l’ uso di unione anziché persist può causare un’istruzione SQL ridondante , che pertanto influisce sulle prestazioni.

Inoltre, chiamare l’unione per le quadro gestite è anche un errore poiché le entity framework gestite vengono automaticamente gestite da Hibernate e il loro stato è sincronizzato con il record del database dal meccanismo di controllo sporco durante lo svuotamento del contesto di persistenza .