INSERT Statement in JPA

1. Oversikt

I denne raske opplæringen lærer vi hvordan du gjør det utføre en INSERT-setning på JPA-objekter.

For mer informasjon om dvale generelt, sjekk ut vår omfattende guide til JPA med vår og introduksjon til vårdata med JPA for dype dykk i dette emnet.

2. Vedvarende objekter i JPA

I JPA håndteres hver enhet som går fra en forbigående til administrert tilstand automatisk av EntityManager.

De EntityManager sjekker om en gitt enhet allerede eksisterer og bestemmer deretter om den skal settes inn eller oppdateres. På grunn av denne automatiske administrasjonen, than bare uttalelser tillatt av JPA er SELECT, UPDATE og SLETT.

I eksemplene nedenfor ser vi på forskjellige måter å administrere og omgå denne begrensningen på.

3. Definere en felles modell

La oss starte med å definere en enkel enhet som vi vil bruke gjennom denne opplæringen:

@Entity offentlig klasse Person {@Id privat Lang id; privat streng fornavn; privat streng etternavn; // standard getters and setters, default og all-args constructors}

La oss også definere en depotklasse som vi vil bruke til implementeringene våre:

@Repository public class PersonInsertRepository {@PersistenceContext private EntityManager entityManager; }

I tillegg vil vi bruke @Transaksjonell kommentar for å håndtere transaksjoner automatisk innen våren. På denne måten trenger vi ikke å bekymre oss for å lage transaksjoner med vår EntityManager, begå endringene våre, eller utføre tilbakestilling manuelt i tilfelle et unntak.

4. createNativeQuery

For manuelt opprettede spørsmål kan vi bruke EntityManager # createNativeQuery metode. Det lar oss lage alle typer SQL-spørringer, ikke bare de som støttes av JPA. La oss legge til en ny metode i depotklassen vår:

@ Transaksjonell offentlig ugyldig insertWithQuery (personperson) {entityManager.createNativeQuery ("INSERT INTO person (id, first_name, last_name) VALUES (?,?,?)") .SetParameter (1, person.getId ()) .setParameter (2 , person.getFirstName ()) .setParameter (3, person.getLastName ()) .executeUpdate (); }

Med denne tilnærmingen må vi definere en bokstavelig forespørsel som inkluderer navn på kolonnene og angi tilsvarende verdier.

Vi kan nå teste depotet vårt:

@Test offentlig ugyldig gittPersonEntity_whenInsertedTwiceWithNativeQuery_thenPersistenceExceptionExceptionIsThrown () {Person person = new Person (1L, "firstname", "lastname"); assertThatExceptionOfType (PersistenceException.class) .isThrownBy (() -> {personInsertRepository.insertWithQuery (PERSON); personInsertRepository.insertWithQuery (PERSON);}); }

I vår test prøver hver operasjon å sette inn en ny oppføring i databasen vår. Siden vi prøvde å sette inn to enheter med det samme id, mislykkes den andre innsettingsoperasjonen ved å kaste a PersistenceException.

Prinsippet her er det samme hvis vi bruker Spring Data @Spørsmål.

5. fortsette

I vårt forrige eksempel opprettet vi innsettingsspørsmål, men vi måtte opprette bokstavelige spørsmål for hver enhet. Denne tilnærmingen er ikke veldig effektiv og resulterer i mye kode på kokerplaten.

I stedet kan vi benytte oss av fortsette metode fra EntityManager.

Som i vårt forrige eksempel, la oss utvide depotklassen med en tilpasset metode:

@Transactional public void insertWithEntityManager (Person person) {this.entityManager.persist (person); }

Nå kan vi teste vår tilnærming igjen:

@Test public void givenPersonEntity_whenInsertedTwiceWithEntityManager_thenEntityExistsExceptionIsThrown () {assertThatExceptionOfType (EntityExistsException.class) .isThrownBy (() -> {personInsertRepository.insertWithEntityManager (ny person (1L, "fornavn", "etternavn")); personInsertRepository.insertWithEntityManager (ny person (1L, "fornavn Etternavn")); }); }

I motsetning til å bruke innfødte spørsmål, vi trenger ikke å spesifisere kolonnenavn og tilsvarende verdier. I stedet, EntityManager håndterer det for oss.

I testen ovenfor, forventer vi også EntityExistsException å bli kastet i stedet for superklassen PersistenceException som er mer spesialisert og kastet av fortsette.

På den annen side, i dette eksemplet, må vi sørge for at vi kaller vår innsettingsmetode hver gang med en ny forekomst av Person.Ellers vil den allerede bli administrert av EntityManager, resulterer i en oppdateringsoperasjon.

6. Konklusjon

I denne artikkelen illustrerte vi måter å utføre innsettingsoperasjoner på JPA-objekter på. Vi så på eksempler på bruk av en innfødt spørring, samt bruk EntityManager # vedvarer for å lage tilpassede INSERT-setninger.

Som alltid er den komplette koden som brukes i denne artikkelen tilgjengelig på GitHub.