Hibernate: save, continue, update, merge, saveOrUpdate

Johdanto

tässä artikkelissa käsitellään useiden Istuntorajapinnan menetelmien välisiä eroja: save, continue, update, merge, saveOrUpdate.

tämä ei ole Johdatus Hibernateen, ja sinun pitäisi jo tuntea konfiguroinnin perusteet, objekti-relaatiokartoitus ja työskentely entiteettiesiintymien kanssa. Saat johdantoartikkelin Hibernate, käy opetusohjelma Hibernate 4 kevään kanssa.

Jatkoluku:

objektien poistaminen Hibernatessa

pikaopas olion poistamiseen Hibernatessa.
Lue lisää →

tallennetut menettelyt, joissa Hibernate

tässä artikkelissa käsitellään lyhyesti sitä, miten voit soittaa myymälätoimenpiteisiin Hibernatesta.
Lue lisää →

yleiskatsaus tunnisteista Hibernate / JPA

Opi kartoittamaan entiteettitunnisteita Hibernatella.
Lue lisää →

istunto pysyvänä asiayhteyden toteutuksessa

Istuntorajapinnassa on useita menetelmiä, jotka lopulta johtavat tietojen tallentamiseen tietokantaan: säily, Tallenna, Päivitä, yhdistä, saveOrUpdate. Jotta ymmärtäisimme näiden menetelmien välisen eron, meidän on ensin keskusteltava istunnon tarkoituksesta pysyvänä asiayhteytenä ja olio-instanssien tilojen välisestä erosta suhteessa istuntoon.

meidän tulisi myös ymmärtää Hibernaten kehityshistoria, joka johti joihinkin osittain päällekkäisiin API-menetelmiin.

2.1. Hallining Entity Instances

object-relational mapping sinällään, yksi ongelmista, jotka Hibernate oli tarkoitettu ratkaisemaan, on ongelma hallita entiteettejä suorituksen aikana. Käsite ”pysyvyys yhteydessä” on Hibernate ratkaisu tähän ongelmaan. Pysyvyyskontekstia voidaan pitää säilönä tai ensimmäisen tason välimuistina kaikille objekteille, jotka latasit tai tallennit tietokantaan istunnon aikana.

istunto on looginen tapahtuma, jonka rajat määritellään sovelluksesi liiketoimintalogiikan mukaan. Kun työskentelet tietokannan kanssa pysyvyyskontekstin kautta, ja kaikki entiteettiesiintymäsi on liitetty tähän kontekstiin, sinulla pitäisi aina olla yksi entiteettiesiintymä jokaista tietokantatietuetta varten, jonka kanssa Olet ollut vuorovaikutuksessa istunnon aikana.

horrostilassa pysyvyyttä kuvaa org.horrostila.Istuntoesimerkki. Javax on edustajainhuoneen jäsen.pysyvyys.EntityManager. Kun käytämme Hibernatea yhteisen parlamentaarisen edustajakokouksen tarjoajana ja toimimme EntityManager-rajapinnan kautta, tämän käyttöliittymän toteutus käytännössä kietoo taustalla olevan Istuntoobjektin. Hibernate Session tarjoaa kuitenkin rikkaamman käyttöliittymän, jossa on enemmän mahdollisuuksia, joten joskus on hyödyllistä työskennellä Session kanssa suoraan.

2.2. States of Entity Instances

mikä tahansa entiteettiesiintymä hakemuksessasi esiintyy yhdessä kolmesta päätilasta istunnon pysyvyyden kontekstissa:

  • transient — tämä instanssi ei ole, eikä koskaan ollut, liitetty istuntoon; tällä instanssilla ei ole vastaavia rivejä tietokannassa; se on yleensä vain uusi objekti, jonka olet luonut tallentaaksesi tietokantaan;
  • jatkuva-tämä ilmentymä liittyy ainutlaatuiseen Istuntoobjektiin; kun istunto vedetään tietokantaan, tällä entiteetillä on taatusti vastaava johdonmukainen tietueet tietokannassa;
  • irrotettu — tämä ilmentymä liitettiin kerran istuntoon (pysyvässä tilassa), mutta nyt se ei ole; ilmentymä tulee tähän tilaan, jos häädät sen kontekstista, tyhjennät tai suljet istunnon tai laitat esiintymän sarjallistamisen/deserialisoinnin kautta.

tässä on yksinkertaistettu tilakaavio, jossa on kommentteja Sessiometodeista, joilla tilan siirtymät tapahtuvat.

2016-07-11_13-38-11

kun entiteettiesiintymä on pysyvässä tilassa, kaikki muutokset, jotka teet tämän ilmentymän yhdistettyihin kenttiin, sovelletaan vastaaviin tietokantatietueisiin ja kenttiin istunnon huuhtelun yhteydessä. Pysyvä ilmentymä voidaan ajatella ”online”, kun taas irrallinen ilmentymä on mennyt” offline ” ja ei seurata muutoksia.

tämä tarkoittaa sitä, että kun vaihdat pysyvän objektin kenttiä, sinun ei tarvitse kutsua Tallenna, Päivitä tai mitään näistä menetelmistä saadaksesi nämä muutokset tietokantaan: sinun tarvitsee vain toimittaa tapahtuma tai huuhdella tai sulkea istunto, kun olet tehnyt sen.

2.3. YPA-spesifikaation mukaisuus

Hibernate oli onnistunein Java ORM-toteutus. Ei ihme, että Java persistence API (JPA) – spesifikaatioon vaikutti voimakkaasti Hibernate API. Valitettavasti eroja oli myös paljon: osa suuria, osa hienovaraisempia.

yhteisen parlamentaarisen edustajakokouksen standardin täytäntöönpanemiseksi Hibernaten sovellusliittymiä oli tarkistettava. Session interface-käyttöliittymään lisättiin useita menetelmiä vastaamaan EntityManager-käyttöliittymää. Nämä menetelmät palvelevat samaa tarkoitusta kuin” alkuperäiset ” menetelmät, mutta ovat spesifikaation mukaisia ja siten niillä on joitakin eroja.

erot operaatioiden välillä

on tärkeää ymmärtää alusta alkaen, että kaikki menetelmät (säilyminen, tallentaminen, päivitys, yhdistäminen, saveorupdaatti) eivät välittömästi johda vastaaviin SQL-päivityksiin tai lisää väittämiin. Varsinainen tietojen tallentaminen tietokantaan tapahtuu tapahtuman toteuttamisen tai istunnon huuhtelun yhteydessä.

mainituilla menetelmillä hallitaan periaatteessa entiteettiesiintymien tilaa siirtämällä niitä eri olomuotojen välillä elinkaaren aikana.

esimerkkiyksikkönä käytetään yksinkertaista huomautuksella kartoitettua entiteettihenkilöä:

@Entitypublic class Person { @Id @GeneratedValue private Long id; private String name; // ... getters and setters}

3.1. Säilyvyys

säilymismenetelmä on tarkoitettu uuden entiteettiesimerkin lisäämiseen pysyvyyskontekstiin eli instanssin siirtämiseen ohimenevästä pysyvään tilaan.

kutsumme sitä yleensä, kun haluamme lisätä tietueen tietokantaan (säily olio-instanssi):

Person person = new Person();person.setName("John");session.persist(person);

mitä tapahtuu, kun itsepintaista menetelmää kutsutaan? Henkilöobjekti on siirtynyt ohimenevästä pysyvään tilaan. Kohde on nyt pysyvyyskontekstissa, mutta ei vielä tallennettu tietokantaan. INSERT-lausumien luominen tapahtuu vasta tapahtuman käynnistämisen, huuhtelun tai istunnon sulkemisen yhteydessä.

huomaa, että säilymismenetelmällä on mitätön palautustyyppi. Se toimii ohitetulla esineellä ”paikallaan”, muuttaen sen tilaa. Persoonamuuttuja viittaa varsinaiseen pysyvään kohteeseen.

tämä menetelmä on myöhempi lisäys Istuntoliittymään. Menetelmän tärkein erottava piirre on se, että se on JSR-220-spesifikaation (EJB-pysyvyys) mukainen. Tämän menetelmän semantiikka on tarkasti määritelty spesifikaatiossa, jossa periaatteessa todetaan, että:

  • ohimenevästä instanssista tulee pysyvä (ja operaatio kaskadoituu kaikkiin suhteisiinsa cascadeen=jatkuvat tai cascadiin=kaikki),
  • jos instanssi on jo pysyvä, tällä kutsulla ei ole vaikutusta tähän nimenomaiseen instanssiin (mutta se kaskadoituu edelleen suhteisiinsa cascadeen=jatkuvat tai cascadiin=kaikki),
  • jos instanssi on irrallaan, on varauduttava poikkeukseen, joko tämän menetelmän kutsuessa, tai istuntoa suoritettaessa tai huuhdeltaessa.

huomaa, että tässä ei ole mitään instanssin tunnisteeseen liittyvää. Spec ei kerro, että id luodaan heti, riippumatta id generation strategia. Itsepintaisen menetelmän erittely antaa toteutukselle mahdollisuuden antaa lausuntoja ID: n tuottamiseksi commit-tai flush-ohjelmassa, eikä id: tä voida taata non-null: ksi tämän menetelmän kutsumisen jälkeen, joten sinun ei pitäisi luottaa siihen.

tätä menetelmää voi kutsua jo pysyväksi esiintymäksi, eikä mitään tapahdu. Mutta jos yrität jatkaa irrallista instanssia, toteutus heittää väkisinkin poikkeuksen. Seuraavassa esimerkissä säilytämme kokonaisuuden, häädämme sen kontekstista, jotta se irtaantuu, ja sitten yritämme jatkaa sitä. Toinen kutsu istuntoon.jatkuva () aiheuttaa poikkeuksen, joten seuraava koodi ei toimi:

Person person = new Person();person.setName("John");session.persist(person);session.evict(person);session.persist(person); // PersistenceException!

3.2. Tallenna

save-menetelmä on” alkuperäinen ” Hibernate-menetelmä, joka ei ole yhteisen parlamentaarisen edustajakokouksen määrittelyn mukainen.

sen käyttötarkoitus on periaatteessa sama kuin säilyneillä, mutta siinä on erilaisia toteutuksen yksityiskohtia. Dokumentaatio tämän menetelmän tiukasti todetaan, että se jatkuu esimerkiksi, ”ensin määrittää luotu tunniste”. Menetelmä palauttaa taatusti tämän tunnisteen sarjamuotoisen arvon.

Person person = new Person();person.setName("John");Long id = (Long) session.save(person);

jo olemassa olevan instanssin tallentamisen vaikutus on sama kuin säilyvän instanssin kohdalla. Ero tulee, kun yrität tallentaa irrallinen instanssi:

Person person = new Person();person.setName("John");Long id1 = (Long) session.save(person);session.evict(person);Long id2 = (Long) session.save(person);

id2-muuttuja eroaa id1: stä. Tallennuspyyntö erilliselle esiintymälle luo uuden pysyvän esiintymän ja antaa sille uuden tunnisteen, joka johtaa päällekkäiseen tietueeseen tietokantaan toimittamisen tai huuhtelun yhteydessä.

3.3. Merge

yhdistämismenetelmän pääasiallinen tarkoitus on päivittää pysyvä olio-ilmentymä erillisestä olio-ilmentymästä saaduilla uusilla kenttäarvoilla.

Oletetaan esimerkiksi, että sinulla on levollinen käyttöliittymä, jossa on menetelmä JSON-sarjan objektin hakemiseksi sen id: n mukaan soittajalle ja menetelmä, joka saa tästä kohteesta päivitetyn version soittajalta. Yhteisö, joka on käynyt läpi tällaisen sarjallistamisen/deserialisaation, ilmestyy erillisenä.

kun olet hylännyt tämän entiteettiesiintymän, sinun on haettava pysyvä entiteettiesiintymä pysyvyyskontekstista ja päivitettävä sen kentät tämän irrallisen ilmentymän uusilla arvoilla. Joten yhdistämistapa tekee juuri niin:

  • löytää entiteettiyksilön tunnisteella, joka on otettu hyväksytystä objektista (joko olemassa oleva entiteettiesimerkki pysyvyyskontekstista noudetaan tai uusi ilmentymä Ladataan tietokannasta);
  • kopioi hyväksytyn objektin kentät tähän ilmentymään;
  • palauttaa äskettäin päivitetyn ilmentymän.

seuraavassa esimerkissä häädämme (irrotamme) tallennetun olion kontekstista, vaihdamme nimikentän ja yhdistämme sitten irroitetun olion.

Person person = new Person(); person.setName("John"); session.save(person);session.evict(person);person.setName("Mary");Person mergedPerson = (Person) session.merge(person);

huomaa, että yhdistämistapa palauttaa objektin — se on mergedperson-objekti, joka ladattiin pysyvyyskontekstiin ja päivitettiin, ei henkilöobjekti, jonka ohitit argumenttina. Nämä ovat kaksi eri objektia, ja henkilö objekti on yleensä hylättävä (joka tapauksessa, älä luota siihen, että se on liitetty pysyvyys yhteydessä).

kuten säilyvyysmenetelmässä, yhdistämistapa on määritelty JSR-220: ssä siten, että siinä on tiettyjä semantiikoita, joihin voi luottaa:

  • jos Olio on irrallinen, se kopioidaan olemassa olevalle pysyvälle entiteetille;
  • jos Olio on ohimenevä, se kopioidaan vasta perustetulle pysyvälle entiteetille;
  • tämä operaatio cascades for all relations with cascade=MERGE or cascade=ALL mapping;
  • jos Olio on pysyvä, tällä menetelmäkutsulla ei ole vaikutusta siihen (mutta cascading tapahtuu edelleen).

3.4. Päivitä

kuten säily ja tallenna, päivitysmenetelmä on ”alkuperäinen” Hibernate-menetelmä, joka oli olemassa kauan ennen yhdistämismenetelmän lisäämistä. Sen semantiikka eroaa useissa avainkohdissa:

  • se vaikuttaa ohitettuun kohteeseen (sen palautustyyppi on mitätön); päivitysmenetelmä siirtää ohitettavan kohteen irrallisesta pysyvään tilaan;
  • tämä menetelmä tekee poikkeuksen, jos ohitat sen ohimenevän yksikön.

seuraavassa esimerkissä Tallennamme kohteen, sitten häädämme (irrotamme) sen kontekstista, sitten muutamme sen nimen ja kutsumme päivityksen. Huomaa, että emme laita päivitysoperaation tulosta erilliseen muuttujaan, koska päivitys tapahtuu itse henkilöobjektille. Periaatteessa kiinnitämme olemassa olevan entiteetin ilmentymän pysyvyyskontekstiin – mitä yhteisen edustajakokouksen määrittely ei salli meidän tehdä.

Person person = new Person();person.setName("John");session.save(person);session.evict(person);person.setName("Mary");session.update(person);

tilapäisen instanssin päivityspyynnön yrittäminen johtaa poikkeukseen. Seuraavat eivät toimi:

Person person = new Person();person.setName("John");session.update(person); // PersistenceException!

3.5. Saveorupdaatti

tämä menetelmä esiintyy vain Hibernate API: ssa, eikä sillä ole standardoitua vastinetta. Samanlainen päivitys, sitä voidaan käyttää myös uudelleen kiinnittämiseen tapauksissa.

itse asiassa päivitysmenetelmää käsittelevä sisäinen DefaultUpdateEventListener-luokka on Defaultsaveorupdatelistenerin alaluokka, joka vain ohittaa joitakin toimintoja. Tärkein ero saveOrUpdate menetelmä on, että se ei heittää poikkeus sovellettaessa ohimenevä esiintymä; sen sijaan, se tekee tästä ohimenevä esiintymä pysyviä. Seuraava koodi säilyttää äskettäin luodun henkilön ilmentymän:

Person person = new Person();person.setName("John");session.saveOrUpdate(person);

tätä menetelmää voidaan pitää yleisenä työkaluna, jolla esine saadaan pysyväksi riippumatta siitä, onko se ohimenevä vai irrallinen.

mitä käyttää?

jos sinulla ei ole mitään erityisvaatimuksia, nyrkkisääntönä on, että sinun tulee noudattaa jatkumo-ja yhdistämistapoja, koska ne ovat standardoituja ja taatusti yhteisen parlamentaarisen edustajakokouksen vaatimusten mukaisia.

ne ovat myös kannettavia siltä varalta, että päätät vaihtaa toiseen pysyvyyden tarjoajaan, mutta ne saattavat joskus vaikuttaa vähemmän hyödyllisiltä kuin ”alkuperäiset” Hibernate-menetelmät, save, update ja saveOrUpdate.

Conclusion

olemme keskustelleet eri Hibernate-Istuntomenetelmien tarkoituksesta liittyen pysyvien kokonaisuuksien hallintaan suoritusajassa. Olemme oppineet, miten nämä menetelmät transist entiteetti esiintymiä läpi niiden elinkaaren ja miksi jotkut näistä menetelmistä ovat päällekkäisiä toimintoja.



+