@DynamicUpdate con Spring Data JPA

1. Panoramica

Quando utilizziamo Spring Data JPA con Hibernate, possiamo utilizzare anche le funzionalità aggiuntive di Hibernate. @DynamicUpdate è una di queste funzionalità.

@DynamicUpdate è un'annotazione a livello di classe che può essere applicata a un'entità JPA. Assicura che Hibernate utilizzi solo le colonne modificate nell'istruzione SQL che genera per l'aggiornamento di un'entità .

In questo articolo, daremo un'occhiata all'annotazione @DynamicUpdate , con l'aiuto di un esempio JPA Spring Data .

2. JPA @Entity

All'avvio di un'applicazione, Hibernate genera le istruzioni SQL per le operazioni CRUD di tutte le entità. Queste istruzioni SQL vengono generate una volta e vengono memorizzate nella cache, in memoria, per migliorare le prestazioni.

L'istruzione di aggiornamento SQL generata include tutte le colonne di un'entità. Nel caso in cui aggiorniamo un'entità, i valori delle colonne modificate vengono passati all'istruzione di aggiornamento SQL. Per le colonne che non vengono aggiornate, Hibernate utilizza i valori esistenti per l'aggiornamento.

Proviamo a capirlo con un esempio. Innanzitutto, consideriamo un'entità JPA denominata Account :

@Entity public class Account { @Id private int id; @Column private String name; @Column private String type; @Column private boolean active; // Getters and Setters }

Quindi, scriviamo un repository JPA per l' entità Account :

@Repository public interface AccountRepository extends JpaRepository { }

Ora useremo AccountRepository per aggiornare il campo del nome di un oggetto Account :

Account account = accountRepository.findOne(ACCOUNT_ID); account.setName("Test Account"); accountRepository.save(account);

Dopo aver eseguito questo aggiornamento, possiamo verificare l'istruzione SQL generata. L'istruzione SQL generata includerà tutte le colonne di Account :

update Account set active=?, name=?, type=? where id=?

3. JPA @Entity con @DynamicUpdate

Abbiamo visto che anche se abbiamo modificato solo il campo del nome , Hibernate ha incluso tutte le colonne nell'istruzione SQL.

Ora aggiungiamo l' annotazione @DynamicUpdate all'entità Account :

@Entity @DynamicUpdate public class Account { // Existing data and methods }

Successivamente, eseguiamo lo stesso codice di aggiornamento che abbiamo usato nella sezione precedente. Possiamo vedere che l'SQL generato da Hibernate, in questo caso, include solo la colonna del nome :

update Account set name=? where id=?

Quindi, cosa succede quando usiamo @DynamicUpdate su un'entità ?

In realtà, quando usiamo @DynamicUpdate su un'entità, Hibernate non usa l'istruzione SQL memorizzata nella cache per l'aggiornamento. Invece, genererà un'istruzione SQL ogni volta che aggiorniamo l'entità. Questo SQL generato include solo le colonne modificate .

Per scoprire le colonne modificate, Hibernate deve tenere traccia dello stato dell'entità corrente. Quindi, quando modifichiamo qualsiasi campo di un'entità, confronta lo stato corrente e quello modificato dell'entità.

Ciò significa che @ DynamicUpdate ha un overhead delle prestazioni ad esso associato . Pertanto, dovremmo usarlo solo quando è effettivamente richiesto.

Certamente, ci sono alcuni scenari in cui dovremmo usare questa annotazione, ad esempio se un'entità rappresenta una tabella che ha un numero elevato di colonne e solo alcune di queste colonne devono essere aggiornate frequentemente. Inoltre, quando usiamo il blocco ottimistico senza versione, dobbiamo usare @DynamicUpdate .

4. Conclusione

In questo tutorial, abbiamo esaminato l' annotazione @DynamicUpdate di Hibernate. Abbiamo utilizzato un esempio di Spring Data JPA per vedere @DynamicUpdate in azione. Inoltre, abbiamo discusso quando dovremmo usare questa funzione e quando non dovremmo.

Come sempre, gli esempi di codice completi utilizzati in questo tutorial sono disponibili su Github.