Spring Data JPA @Modifying Annotation

1. Einleitung

In diesem kurzen Tutorial erfahren Sie, wie Sie Aktualisierungsabfragen mit der Spring Data JPA @Query- Annotation erstellen . Dies erreichen wir mit der Annotation @Modifying .

Zuerst aktualisieren wir unseren Speicher und sehen, wie mit Spring Data JPA Abfragen durchgeführt werden. Danach werden wir uns eingehend mit der Verwendung von Annotationen @Query und @Modifying befassen . Abschließend erfahren Sie, wie Sie den Status unseres Persistenzkontexts verwalten, wenn Sie Abfragen ändern.

2. Abfragen in Spring Data JPA

Lassen Sie uns zunächst die drei Mechanismen zusammenfassen, die Spring Data JPA zum Abfragen von Daten in einer Datenbank bereitstellt :

  • Abfragemethoden
  • @Query Annotation
  • Benutzerdefinierte Repository-Implementierung

Erstellen wir eine Benutzerklasse und ein passendes Spring Data JPA-Repository, um diese Mechanismen zu veranschaulichen:

@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 {}

Der Abfragemethodenmechanismus ermöglicht es uns, die Daten zu manipulieren, indem die Abfragen aus den Methodennamen abgeleitet werden:

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

In diesem Beispiel finden wir eine Abfrage, mit der Benutzer anhand ihrer Namen abgerufen werden, oder eine Abfrage, mit der Benutzer entfernt werden, deren Erstellungsdatum nach einem bestimmten Datum liegt.

Die @Query- Annotation bietet uns die Möglichkeit, eine bestimmte JPQL- oder SQL-Abfrage in die @ Query- Annotation zu schreiben :

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

In diesem Codefragment sehen wir eine Abfrage, in der Benutzer mit einer @ gmail.com- E-Mail-Adresse abgerufen werden .

Der erste Mechanismus ermöglicht es uns, Daten abzurufen oder zu löschen. Was die zweite betrifft, können wir so ziemlich jede Abfrage ausführen. Jedoch für Abfragen zu aktualisieren, müssen wir das hinzufügen @Modifying Anmerkung . Dies wird das Thema dieses Tutorials sein.

3. Verwenden der @ Modifying Annotation

Die Annotation @Modifying wird verwendet, um die Annotation @Query zu erweitern und nicht nur SELECT- Abfragen, sondern auch INSERT- , UPDATE- , DELETE- und sogar DDL- Abfragen auszuführen .

Lassen Sie uns ein wenig mit dieser Anmerkung spielen und sehen, woraus sie besteht.

Schauen wir uns zunächst ein Beispiel für eine @ Modifying UPDATE-Abfrage an:

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

Hier deaktivieren wir die Benutzer, die sich seit einem bestimmten Datum nicht mehr angemeldet haben.

Versuchen wir es mit einem anderen, bei dem deaktivierte Benutzer gelöscht werden:

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

Wie wir sehen können, gibt diese Methode eine Ganzzahl zurück. Es ist eine Funktion von Spring Data JPA @ Modifying- Abfragen, die uns die Anzahl der aktualisierten Entitäten angibt .

Wir sollten beachten, dass das Ausführen einer Löschabfrage mit @Query anders funktioniert als die von Spring Data JPA mit dem Namen deleteBy abgeleiteten Abfragemethoden. Letzterer ruft zuerst die Entitäten aus der Datenbank ab und löscht sie dann nacheinander. Dies bedeutet also, dass die Lebenszyklusmethode @PreRemove für diese Entitäten aufgerufen wird. Bei ersteren wird jedoch eine einzelne Abfrage für die Datenbank ausgeführt.

Zuletzt fügen wir unserer USERS- Tabelle eine gelöschte Spalte mit einer DDL- Abfrage hinzu:

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

Leider lässt die Verwendung von Änderungsabfragen den zugrunde liegenden Persistenzkontext veraltet. Es ist jedoch möglich, diese Situation zu bewältigen. Das ist das Thema des nächsten Abschnitts.

4. Verwalten des Persistenzkontexts

Wenn unsere modifizierende Abfrage Entitäten ändert, die im Persistenzkontext enthalten sind, ist dieser Kontext veraltet. Eine Möglichkeit, diese Situation zu bewältigen, besteht darin, den Persistenzkontext zu löschen. Auf diese Weise stellen wir sicher, dass der Persistenzkontext die Entitäten beim nächsten Mal aus der Datenbank abruft.

However, we don't have to explicitly call the clear() method on the EntityManager. We can just use the clearAutomatically property from the @Modifying annotation:

@Modifying(clearAutomatically = true)

That way, we make sure that the persistence context is cleared after our query execution.

But, what if our persistence context contained unflushed changes? Therefore, clearing it would mean dropping unsaved changes. Fortunately, there's another property of the annotation we can use – flushAutomatically:

@Modifying(flushAutomatically = true)

Now, the EntityManager is flushed before our query is executed.

5. Conclusion

Damit ist dieser kurze Artikel über die Annotation @Modifying abgeschlossen . Wir haben gesehen, wie diese Annotation verwendet wird, um Aktualisierungsabfragen wie INSERT, UPDATE, DELETE und sogar DDL auszuführen . Danach haben wir gelernt, wie der Status des Persistenzkontexts mit den Eigenschaften clearAutomatically und flushAutomatically verwaltet wird .

Wie üblich ist der vollständige Code für diesen Artikel auf GitHub verfügbar.