Spring Data JPA @Modifying Annotation

1. Introduzione

In questo breve tutorial, impareremo come creare query di aggiornamento con l' annotazione Spring Data JPA @Query . Otterremo questo risultato utilizzando l' annotazione @Modifying .

Innanzitutto, aggiorneremo la nostra memoria e vedremo come eseguire query utilizzando Spring Data JPA. Dopodiché, approfondiremo l'uso delle annotazioni @Query e @Modifying . Infine, vedremo come gestire lo stato del nostro contesto di persistenza quando si utilizzano le query di modifica.

2. Query in Spring Data JPA

Innanzitutto, ricapitoliamo i 3 meccanismi forniti da Spring Data JPA per eseguire query sui dati in un database :

  • Metodi di query
  • @Query annotazione
  • Implementazione del repository personalizzato

Creiamo una classe utente e un repository JPA Spring Data corrispondente per illustrare questi meccanismi:

@Entity @Table(name = "users", schema = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; private LocalDate creationDate; private LocalDate lastLoginDate; private boolean active; private String email; }
public interface UserRepository extends JpaRepository {}

Il meccanismo dei metodi di query ci consente di manipolare i dati derivando le query dai nomi dei metodi:

List findAllByName(String name); void deleteAllByCreationDateAfter(LocalDate date);

In questo esempio, possiamo trovare una query che recupera gli utenti in base al loro nome, o ancora una query che rimuove gli utenti che hanno una data di creazione dopo una certa data.

Per quanto riguarda il @ query annotazione, ci fornisce la possibilità di scrivere una specifica JPQL o SQL query nel @query annotazioni :

@Query("select u from User u where u.email like '%@gmail.com'") List findUsersWithGmailAddress();

In questo frammento di codice, possiamo vedere una query che recupera gli utenti che hanno un indirizzo email @ gmail.com .

Il primo meccanismo ci consente di recuperare o eliminare i dati. Per quanto riguarda il secondo, ci consente di eseguire praticamente qualsiasi query. Tuttavia, per aggiornare le query, dobbiamo aggiungere l' annotazione @Modifying . Questo sarà l'argomento di questo tutorial.

3. Utilizzando il @Modifying Annotazione

L' annotazione @Modifying viene utilizzata per migliorare l' annotazione @Query per eseguire non solo le query SELECT ma anche le query INSERT , UPDATE , DELETE e persino DDL .

Giochiamo un po 'con questa annotazione e vediamo di cosa è fatta.

Per prima cosa, vediamo un esempio di una query @Modifying UPDATE:

@Modifying @Query("update User u set u.active = false where u.lastLoginDate < :date") void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);

Qui, stiamo disattivando gli utenti che non hanno effettuato l'accesso da una determinata data.

Proviamone un altro in cui elimineremo gli utenti disattivati:

@Modifying @Query("delete User u where u.active = false") int deleteDeactivatedUsers();

Come possiamo vedere, questo metodo restituisce un numero intero. È una funzionalità delle query Spring Data JPA @Modifying che ci fornisce il numero di entità aggiornate.

Dobbiamo notare che l'esecuzione di una query di eliminazione con @Query funziona in modo diverso dai metodi di query derivati dal nome di Spring Data JPA deleteBy . Quest'ultimo recupera prima le entità dal database e poi le elimina una per una. Quindi, questo significa che il metodo del ciclo di vita @PreRemove verrà chiamato su quelle entità. Tuttavia, con il primo, viene eseguita una singola query sul database.

Infine, aggiungiamo una colonna eliminata alla nostra tabella USERS con una query DDL :

@Modifying @Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true) void addDeletedColumn();

Sfortunatamente, l'utilizzo di query di modifica lascia il contesto di persistenza sottostante obsoleto. Tuttavia, è possibile gestire questa situazione. Questo è l'argomento della prossima sezione.

4. Gestione del contesto di persistenza

Se la nostra query di modifica cambia le entità contenute nel contesto di persistenza, allora questo contesto diventa obsoleto. Un modo per gestire questa situazione è cancellare il contesto di persistenza. In questo modo, ci assicuriamo che il contesto di persistenza recupererà le entità dal database la prossima volta.

Tuttavia, non è necessario chiamare esplicitamente il metodo clear () su EntityManager . Possiamo semplicemente usare la proprietà clearAutomatically dall'annotazione @Modifying :

@Modifying(clearAutomatically = true)

In questo modo, ci assicuriamo che il contesto di persistenza venga cancellato dopo la nostra esecuzione della query.

Ma cosa succederebbe se il nostro contesto di persistenza contenesse cambiamenti immutati? Pertanto, cancellarlo significherebbe eliminare le modifiche non salvate. Fortunatamente, c'è un'altra proprietà dell'annotazione che possiamo usare: flushAutomatically :

@Modifying(flushAutomatically = true)

Ora, EntityManager viene scaricato prima che la nostra query venga eseguita.

5. conclusione

Con questo si conclude questo breve articolo sull'annotazione @Modifying . Abbiamo visto come utilizzare questa annotazione per eseguire query di aggiornamento come INSERT, UPDATE, DELETE e persino DDL . Successivamente, abbiamo imparato come gestire lo stato del contesto di persistenza con le proprietà clearAutomatically e flushAutomatically .

Come al solito, il codice completo di questo articolo è disponibile su GitHub.