JPA EntityManager: Hvorfor bruke persist() fremfor merge()?
EntityManager.merge()
kan sette inn nye objekter og oppdatere eksisterende.
Hvorfor skulle man ønske å bruke persist()
(som bare kan opprette nye objekter)?
920
3
Begge måtene legger til en entitet i en PersistenceContext, forskjellen ligger i hva du gjør med entiteten etterpå.
Persist tar en entitetsforekomst, legger den til konteksten og gjør forekomsten administrert (dvs. at fremtidige oppdateringer av entiteten spores).
Merge oppretter en ny forekomst av entiteten, kopierer tilstanden fra den leverte entiteten og gjør den nye kopien administrert. Instansen du sender inn, blir ikke administrert (eventuelle endringer du gjør, blir ikke en del av transaksjonen - med mindre du kaller merge igjen).
Kanskje et kodeeksempel kan være til hjelp.
Scenario 1 og 3 er noenlunde likeverdige, men det finnes noen situasjoner der det kan være lurt å bruke scenario 2.
Jeg la merke til at når jeg brukte
em.merge
, fikk jeg enSELECT
-setning for hverINSERT
, selv når det ikke var noe felt som JPA genererte for meg - primærnøkkelfeltet var en UUID som jeg satte selv. Jeg byttet tilem.persist(myEntityObject)
og fikk bareINSERT
-setninger da.Jeg fikk lazyLoading-unntak på enheten min fordi jeg prøvde å få tilgang til en lazy loaded samling som var i session.
Det jeg gjorde, var å hente entiteten fra økten i en separat forespørsel og deretter prøve å få tilgang til en samling på jsp-siden, noe som var problematisk.
For å avhjelpe dette oppdaterte jeg den samme entiteten i kontrolleren min og sendte den til jsp-siden min, selv om jeg forestiller meg at når jeg lagrer på nytt i sesjonen, vil den også være tilgjengelig via
SessionScope
og ikke kaste enLazyLoadingException
, en modifikasjon av eksempel 2:Følgende har fungert for meg: