Esittely
Tässä opetusohjelmassa käsittelemme Hibernatea ja Java Persistence API:ta (JPA) – ja keskitymme niiden eroihin.
Aloitamme tutkimalla, mikä JPA on, miten sitä käytetään ja mitä keskeisiä käsitteitä sen taustalla on.
Sitten katsomme, miten Hibernate ja EclipseLink sopivat kuvaan.
Object-Relational Mapping
Ennen kuin sukellamme JPA:han, on tärkeää ymmärtää käsite Object-Relational Mapping – joka tunnetaan myös nimellä ORM.
Object-Relational Mapping on yksinkertaisesti minkä tahansa Java-olion persistointi suoraan tietokantataulukkoon. Yleensä siirrettävän objektin nimestä tulee taulukon nimi, ja jokaisesta objektin sisältämästä kentästä tulee sarake. Kun taulukko on perustettu, jokainen rivi vastaa sovelluksen tietuetta.
Esittely JPA:han
Javan pysyvyysrajapinta (Java Persistence API) eli JPA on määrittely, joka määrittelee relaatiotiedon hallinnan Java-sovelluksessa. API kartoittaa joukon käsitteitä, jotka määrittelevät, mitkä sovelluksen sisällä olevat objektit tulisi säilyttää ja miten ne tulisi säilyttää.
On tärkeää huomata, että JPA on vain spesifikaatio ja että se tarvitsee toteutuksen toimiakseen – mutta siitä lisää myöhemmin.
Keskustellaan nyt joistakin JPA:n keskeisistä käsitteistä, jotka toteutuksen on katettava.
3.1. JPA:n käsitteet. Entity
Javax.persistence.Entity-luokka määrittelee, mitkä objektit tulee persistoida tietokantaan. Jokaiselle persistoidulle entiteetille JPA luo uuden taulun valittuun tietokantaan.
Lisäksi kaikkien valittujen entiteettien tulee määritellä primääriavain, jota merkitään @Id-merkinnällä. Yhdessä @GeneratedValue-annotaation kanssa määritellään, että primääriavain luodaan automaattisesti, kun tietue persistoidaan tietokantaan.
Katsotaanpa pikainen esimerkki JPA:n kuvaamasta oliosta.
@Entitypublic class Car { @GeneratedValue @Id public long id; // getters and setters}
Muista, että tällä ei ole tällä hetkellä mitään vaikutusta sovellukseen – JPA ei tarjoa mitään toteutuskoodia.
3.2. JPA:lla ei ole vaikutusta sovellukseen. Kenttien pysyvyys
Toinen JPA:n keskeinen käsite on kenttien pysyvyys. Kun objekti määritellään Javassa olioksi, kaikki sen sisällä olevat kentät persistoidaan automaattisesti eri sarakkeina oliotaulussa.
Jos persistoidun objektin sisällä on kenttä, jota emme halua persistoida tietokantaan, voimme julistaa kentän transientiksi @Transient-annotaatiolla.
3.3. JPA:n kentän persistointi. Suhteet
Seuraavaksi JPA määrittelee, miten meidän tulisi hallita sovelluksessamme eri tietokantataulujen välisiä suhteita. Kuten olemme nähneet, JPA hoitaa tämän annotaatioiden avulla. Suhdeannotaatioita on neljä, jotka meidän on pidettävä mielessä:
- @OneToOne
- @OneToMany
- @ManyToOne
- @ManyToMany
Katsotaanpa, miten tämä toimii:
@Entitypublic class SteeringWheel { @OneToOne private Car car // getters and setters}
Yllä olevassa esimerkissämme SteeringWheel-luokka kuvaa yksi yhteen -suhdetta aiemmin käyttämämme Car-luokan kanssa.
3.4. Entity Manager
Viimeiseksi javax.persistence.EntityManager-luokka määrittelee toiminnot tietokantaan ja tietokannasta. EntityManager sisältää yleiset CRUD-operaatiot (Create, Read, Update ja Delete), jotka persistoidaan tietokantaan.
JPA-toteutukset
JPA-määrittelyn määritellessä, miten ja mitä meidän tulisi persistoida, meidän on nyt valittava toteutuksen toimittaja, joka toimittaa tarvittavan koodin. Ilman tällaista palveluntarjoajaa meidän täytyisi toteuttaa kaikki asiaankuuluvat luokat, jotta ne olisivat JPA:n mukaisia, ja se on paljon työtä!
Tarjoajia on paljon, joista valita, ja jokaisella on omat hyvät ja huonot puolensa. Kun tehdään päätös siitä, mitä käyttää, on syytä ottaa huomioon muutama seuraavista seikoista:
- Projektin kypsyys – kuinka kauan palveluntarjoaja on ollut olemassa ja kuinka hyvin se on dokumentoitu?
- Asiaprojektit – onko palveluntarjoajalla hyödyllisiä aliprojekteja uuden sovelluksemme kannalta?
- Yhteisön tuki – onko joku auttamassa meitä, kun meille tulee kriittinen bugi?
- Benchmarking – kuinka suorituskykyinen toteutus on?
Vaikka emme mene syvälle eri JPA-palveluntarjoajien benchmarkingiin, JPA Performance Benchmark (JPAB) sisältää arvokasta tietoa tästä.
Kun tämä on pois tieltä, tarkastellaan lyhyesti joitakin JPA:n tärkeimpiä tarjoajia.
Hibernate
Ydinominaisuuksiltaan Hibernate on olio-relationaalinen kartoitustyökalu, joka tarjoaa JPA:n toteutuksen. Hibernate on yksi kypsimmistä JPA-toteutuksista, ja sillä on valtava yhteisö projektin tukena.
Se toteuttaa kaikki javax.persistence-luokat, joita tarkastelimme aiemmin artikkelissa, sekä tarjoaa JPA:n ulkopuolisia toimintoja – Hibernate-työkaluja, validointia ja hakua. Vaikka nämä Hibernate-kohtaiset API:t voivat olla hyödyllisiä, niitä ei tarvita sovelluksissa, jotka vaativat vain JPA:n perustoiminnallisuutta.
Katsotaanpa lyhyesti, mitä Hibernate tarjoaa @Entity-annotaatiolla.
Toteuttaessaan JPA-sopimusta @org.hibernate.annotations.Entity lisää JPA-määrittelyä pidemmälle menevää metatietoa. Näin voidaan hienosäätää olioiden pysyvyyttä. Tarkastellaan esimerkiksi muutamia Hibernaten tarjoamia annotaatioita, jotka laajentavat @Entityn toiminnallisuutta:
- @Table – mahdollistaa entiteetille luodun taulukon nimen määrittelyn
- @BatchSize – määrittelee erän koon, kun entiteettejä haetaan taulukosta
On myös syytä huomioida muutama JPA:n määrittelemätön lisäominaisuus, jotka voivat osoittautua hyödyllisiksi suuremmissa sovelluksissa:
- Muokattavat CRUD-lausekkeet @SQLInsert-, @SQLUpate- ja @SQLDelete-annotaatioiden avulla
- Tuki pehmeälle poistamiselle
- Immutoituvat entiteetit @Immutable-annotaatiolla
Jos haluat syvällisemmän sukelluksen Hibernateen ja Javan persistenssisältöön – tutustu Springin persistenssisäilytystä käsittelevään tutoriaalisarjaan.
EclipseLink
Eclipse Foundationin rakentama EclipseLink tarjoaa avoimen lähdekoodin JPA-toteutuksen. Lisäksi EclipseLink tukee useita muita persistenssistandardeja, kuten Java Architecture for XML Binding (JAXB).
Lyhyesti sanottuna, sen sijaan, että objekti persistoitaisiin tietokantariville, JAXB mapittaa sen XML-edustukseen.
Seuraavaksi vertailemalla samaa @Entity-annotaatiototeutusta huomaamme, että EclipseLink tarjoaa jälleen erilaisia laajennuksia. Vaikka @BatchSize-annotaatiota ei ole, kuten aiemmin näimme, EclipseLink tarjoaa muita vaihtoehtoja, joita Hibernate ei tarjoa.
Esimerkiksi:
- @ReadOnly – määrittelee, että persistoitava olio on vain luettavissa
- @Struct – määrittelee luokan, joka mapataan tietokannan ’struct’-tyyppiin
Lukemalla lisää siitä, mitä EclipseLinkillä on tarjottavanaan, voit tutustua oppaaseemme, joka käsitteli opasta aiheesta: EclipseLink with Spring.
Yhteenveto
Tässä artikkelissa tarkastelimme Java Persistence API:ta eli JPA:ta.
Loppujen lopuksi selvitimme, miten se eroaa Hibernatesta ja EclipseLinkistä.