INSERT-verklaring in JPA

1. Overzicht

In deze korte handleiding leren we hoe u dat moet doen voer een INSERT-instructie uit op JPA-objecten.

Voor meer informatie over Hibernate in het algemeen, bekijk onze uitgebreide gids voor JPA met Spring en inleiding tot Spring Data met JPA voor diepgaande duiken in dit onderwerp.

2. Aanhoudende objecten in JPA

In JPA wordt elke entiteit die van een tijdelijke naar een beheerde staat gaat, automatisch afgehandeld door het EntityManager.

De EntityManager controleert of een bepaalde entiteit al bestaat en besluit vervolgens of deze moet worden ingevoegd of bijgewerkt. Door dit automatische beheer tDe enige verklaringen die door JPA zijn toegestaan, zijn SELECT, UPDATE en VERWIJDEREN.

In de onderstaande voorbeelden zullen we verschillende manieren bekijken om deze beperking te beheren en te omzeilen.

3. Een gemeenschappelijk model definiëren

Laten we nu beginnen met het definiëren van een eenvoudige entiteit die we in deze zelfstudie zullen gebruiken:

@Entity openbare klasse Persoon {@Id privé Lange id; private String voornaam; private String achternaam; // standard getters en setters, default en all-args constructors}

Laten we ook een repository-klasse definiëren die we zullen gebruiken voor onze implementaties:

@Repository openbare klasse PersonInsertRepository {@PersistenceContext privé EntityManager entityManager; }

Bovendien passen we de @Transactional annotatie om transacties automatisch af te handelen door Spring. Op deze manier hoeven we ons geen zorgen te maken over het maken van transacties met onze Entiteitsmanager, het doorvoeren van onze wijzigingen, of het handmatig uitvoeren van rollback in het geval van een uitzondering.

4. createNativeQuery

Voor handmatig gemaakte zoekopdrachten kunnen we de EntityManager # createNativeQuery methode. Het stelt ons in staat om elk type SQL-query te maken, niet alleen degene die worden ondersteund door JPA. Laten we een nieuwe methode toevoegen aan onze repository-klasse:

@Transactional public void insertWithQuery (Persoon persoon) {entityManager.createNativeQuery ("INSERT IN person (id, voornaam, achternaam) VALUES (?,?,?)") .SetParameter (1, person.getId ()) .setParameter (2 , person.getFirstName ()) .setParameter (3, person.getLastName ()) .executeUpdate (); }

Met deze benadering moeten we een letterlijke query definiëren, inclusief namen van de kolommen, en de bijbehorende waarden instellen.

We kunnen nu onze repository testen:

@Test openbare ongeldige gegevenPersonEntity_whenInsertedTwiceWithNativeQuery_thenPersistenceExceptionExceptionIsThrown () {Persoon persoon = nieuwe persoon (1L, "voornaam", "achternaam"); assertThatExceptionOfType (PersistenceException.class) .isThrownBy (() -> {personInsertRepository.insertWithQuery (PERSON); personInsertRepository.insertWithQuery (PERSON);}); }

In onze test probeert elke bewerking een nieuw item in onze database in te voegen. Omdat we hebben geprobeerd om twee entiteiten met hetzelfde in te voegen ID kaart, mislukt de tweede insert-bewerking door een PersistenceException.

Het principe is hier hetzelfde als we Spring Data's gebruiken @Query.

5. volharden

In ons vorige voorbeeld hebben we invoegquery's gemaakt, maar we moesten letterlijke query's maken voor elke entiteit. Deze aanpak is niet erg efficiënt en resulteert in veel standaardcode.

In plaats daarvan kunnen we gebruik maken van de volharden methode van EntityManager.

Laten we, net als in ons vorige voorbeeld, onze repository-klasse uitbreiden met een aangepaste methode:

@Transactional public void insertWithEntityManager (Persoon persoon) {this.entityManager.persist (persoon); }

Nu kunnen we onze aanpak opnieuw testen:

@Test openbare ongeldigheid gegevenPersonEntity_whenInsertedTwiceWithEntityManager_thenEntityExistsExceptionIsThrown () {assertThatExceptionOfType (EntityExistsException.class) .isThrownBy (() -> {personInsertRepository.insertory, "personInsertRepository 1, personInsertRepository 1 "voornaam Achternaam")); }); }

In tegenstelling tot het gebruik van native queries, we hoeven geen kolomnamen en bijbehorende waarden op te geven. In plaats daarvan, EntityManager regelt dat voor ons.

In bovenstaande test verwachten we ook EntityExistsException worden gegooid in plaats van zijn superklasse PersistenceException dat is meer gespecialiseerd en gegooid door volharden.

Aan de andere kant moeten we er in dit voorbeeld voor zorgen we noemen onze insert-methode elke keer met een nieuw exemplaar van Persoon.Anders wordt het al beheerd door Entiteitsmanager, resulterend in een updatebewerking.

6. Conclusie

In dit artikel hebben we manieren geïllustreerd om invoegbewerkingen uit te voeren op JPA-objecten. We hebben gekeken naar voorbeelden van het gebruik van een native query en het gebruik van EntityManager # persist om aangepaste INSERT-instructies te maken.

Zoals altijd is de volledige code die in dit artikel wordt gebruikt, beschikbaar op GitHub.