Introduction
In deze tutorial bespreken we Hibernate en de Java Persistence API (JPA) – met een focus op de verschillen tussen beide.
We beginnen met het verkennen van wat JPA is, hoe het wordt gebruikt, en de kernconcepten erachter.
Daarna kijken we hoe Hibernate en EclipseLink in het plaatje passen.
Object-Relational Mapping
Voordat we in JPA duiken, is het belangrijk om het concept van Object-Relational Mapping te begrijpen – ook bekend als ORM.
Object-relational mapping is simpelweg het proces van het persen van een Java-object direct naar een database tabel. Gewoonlijk wordt de naam van het object de naam van de tabel, en elk veld in dat object wordt een kolom. Als de tabel is opgezet, komt elke rij overeen met een record in de applicatie.
An Introduction to JPA
De Java Persistence API, of JPA, is een specificatie die het beheer van relationele gegevens in een Java applicatie definieert. De API brengt een set concepten in kaart die definieert welke objecten binnen de applicatie moeten worden bewaard, en hoe ze moeten worden bewaard.
Het is belangrijk om hier op te merken dat JPA slechts een specificatie is en dat het een implementatie nodig heeft om te werken – maar daarover later meer.
Nu, laten we enkele van de kernconcepten van JPA bespreken die een implementatie moet dekken.
3.1. Entity
De javax.persistence.Entity klasse definieert welke objecten moeten worden geperst naar de database. Voor elke entiteit maakt JPA een nieuwe tabel aan in de gekozen database.
Daarnaast moeten alle gekozen entiteiten een primaire sleutel definiëren, aangeduid met de @Id annotatie. Samen met de @GeneratedValue annotatie definiëren we dat de primaire sleutel automatisch moet worden gegenereerd wanneer het record in de database wordt opgeslagen.
Laten we eens kijken naar een snel voorbeeld van een entiteit die door JPA wordt beschreven.
@Entitypublic class Car { @GeneratedValue @Id public long id; // getters and setters}
Houd in gedachten dat dit momenteel geen effect op de toepassing zal hebben – JPA biedt geen implementatiecode.
3.2. Field Persistence
Een ander kernconcept van JPA is field persistence. Wanneer een object in Java als een entiteit wordt gedefinieerd, worden alle velden daarin automatisch als verschillende kolommen binnen de entiteittabel geperst.
Als er een veld binnen een geperst object is dat we niet naar de database willen persisteren, kunnen we het veld transient declareren met de @Transient annotatie.
3.3. Relaties
Volgende, JPA specificeert hoe we relaties moeten beheren tussen verschillende database tabellen binnen onze applicatie. Zoals we hebben gezien, behandelt JPA dit met annotaties. Er zijn vier relatie-annotaties die we in gedachten moeten houden:
- @OneToOne
- @OneToMany
- @ManyToOne
- @ManyToMany
Laten we eens kijken hoe dit werkt:
@Entitypublic class SteeringWheel { @OneToOne private Car car // getters and setters}
In ons voorbeeld hierboven beschrijft de klasse SteeringWheel een één-op-één relatie met onze klasse Car van eerder.
3.4. Entity Manager
Tot slot specificeert de javax.persistence.EntityManager klasse de operaties van en naar de database. De EntityManager bevat de gebruikelijke Create, Read, Update en Delete (CRUD) operaties die naar de database worden geperst.
JPA Implementaties
Met de JPA specificatie die definieert hoe en wat we moeten persisteren, moeten we nu een implementatie provider kiezen om de benodigde code te leveren. Zonder zo’n leverancier zouden we alle relevante klassen moeten implementeren om aan JPA te voldoen, en dat is een hoop werk!
Er zijn genoeg leveranciers om uit te kiezen, met elk hun eigen voors en tegens. Bij het maken van een beslissing over welke te gebruiken, moeten we overwegen een paar van de volgende punten:
- Project volwassenheid – hoe lang is de provider al bestaat, en hoe goed gedocumenteerd is het?
- Subprojecten – heeft de leverancier nuttige subprojecten voor onze nieuwe toepassing?
- Community support – is er iemand die ons helpt als we met een kritieke bug te maken krijgen?
- Benchmarking – hoe performant is de implementatie?
Hoewel we niet diep zullen ingaan op de benchmarking van verschillende JPA providers, bevat JPA Performance Benchmark (JPAB) een waardevol inzicht hierin.
Met dat uit de weg, laten we een korte blik werpen op enkele van de top aanbieders van JPA.
Hibernate
In de kern is Hibernate een object-relationele mapping tool die een implementatie van JPA biedt. Hibernate is een van de meest volwassen JPA implementaties die er zijn, met een enorme gemeenschap die het project ondersteunt.
Hibernate implementeert alle javax.persistence klassen die we eerder in het artikel hebben bekeken, maar biedt ook functionaliteit die verder gaat dan JPA – Hibernate tools, validatie, en zoeken. Hoewel deze Hibernate-specifieke API’s nuttig kunnen zijn, zijn ze niet nodig in toepassingen die alleen de basis JPA functionaliteit nodig hebben.
Laten we eens een snelle blik werpen op wat Hibernate biedt met de @Entity annotatie.
Hoewel JPA contract vervult, voegt @org.hibernate.annotations.Entity extra metadata toe die verder gaat dan JPA specificatie. Dit maakt het mogelijk om entiteit persistentie te fine-tunen. Laten we bijvoorbeeld eens kijken naar een paar annotaties die door Hibernate worden aangeboden en die de functionaliteit van @Entity uitbreiden:
- @Table – stelt ons in staat om de naam van de tabel op te geven die voor de entiteit is gemaakt
- @BatchSize – specificeert de batchgrootte bij het ophalen van entiteiten uit de tabel
Het is ook de moeite waard om een paar van de extra functies op te merken die de JPA niet specificeert, en die nuttig kunnen blijken in grotere toepassingen:
- Aanpasbare CRUD statements met de @SQLInsert, @SQLUpate en @SQLDelete annotaties
- Support voor soft deleting
- Immutable entiteiten met de @Immutable annotatie
Voor een diepere duik in Hibernate en Java persistentie – ga naar onze Spring persistentie tutorial serie.
EclipseLink
EclipseLink, gebouwd door de Eclipse Foundation, biedt een open-sourced JPA implementatie. Daarnaast ondersteunt EclipseLink een aantal andere persistentiestandaarden, zoals Java Architecture for XML Binding (JAXB).
Vereenvoudig gezegd: in plaats van het persisteren van een object naar een database rij, brengt JAXB het in kaart naar een XML representatie.
Volgende, door dezelfde @Entity annotatie implementatie te vergelijken, zien we dat EclipseLink weer verschillende uitbreidingen biedt. Terwijl er geen annotatie is voor @BatchSize zoals we eerder zagen, biedt EclipseLink andere opties die Hibernate niet biedt.
Bijvoorbeeld:
- @ReadOnly – specificeert dat de te persisteren entiteit read-only is
- @Struct – definieert de klasse om te mappen naar een database ‘struct’ type
Om meer te lezen over wat EclipseLink te bieden heeft, ga dan naar onze gids over EclipseLink met Spring.
Conclusie
In dit artikel hebben we gekeken naar de Java Persistence API, of JPA.
Ten slotte hebben we verkend hoe het verschilt van Hibernate en EclipseLink.