Einführung in Spring Data JPA

1. Übersicht

Dieser Artikel konzentriert sich auf die Einführung von Spring Data JPA in ein Spring-Projekt und die vollständige Konfiguration der Persistenzschicht. Eine schrittweise Einführung zum Einrichten des Spring-Kontexts mithilfe der Java-basierten Konfiguration und des grundlegenden Maven-POM für das Projekt finden Sie in diesem Artikel.

2. Das von Spring Data generierte DAO - Keine DAO-Implementierungen mehr

Wie wir in einem früheren Artikel besprochen haben, besteht die DAO-Schicht normalerweise aus viel Boilerplate-Code, der vereinfacht werden kann und sollte. Die Vorteile einer solchen Vereinfachung sind vielfältig: Verringerung der Anzahl der zu definierenden und zu wartenden Artefakte, Konsistenz der Datenzugriffsmuster und Konsistenz der Konfiguration.

Spring Data geht mit dieser Vereinfachung einen Schritt weiter und ermöglicht es, die DAO-Implementierungen vollständig zu entfernen . Die Schnittstelle des DAO ist jetzt das einzige Artefakt, das wir explizit definieren müssen.

Um das Spring Data-Programmiermodell mit JPA nutzen zu können, muss eine DAO-Schnittstelle die JPA-spezifische Repository- Schnittstelle - JpaRepository - erweitern . Dadurch kann Spring Data diese Schnittstelle finden und automatisch eine Implementierung dafür erstellen.

Durch die Erweiterung der Schnittstelle erhalten wir die relevantesten CRUD-Methoden für den Standarddatenzugriff, die in einem Standard-DAO verfügbar sind.

3. Benutzerdefinierte Zugriffsmethode und Abfragen

Wie bereits erwähnt, werden durch die Implementierung einer der Repository- Schnittstellen im DAO bereits einige grundlegende CRUD-Methoden (und Abfragen) definiert und implementiert .

Um spezifischere Zugriffsmethoden zu definieren, unterstützt Spring JPA einige Optionen:

  • Definieren Sie einfach eine neue Methode in der Schnittstelle
  • Stellen Sie die eigentliche JPQL-Abfrage mithilfe der Annotation @Query bereit
  • Verwenden Sie die erweiterte Unterstützung für Spezifikation und Querydsl in Spring Data
  • Definieren Sie benutzerdefinierte Abfragen über JPA Named Queries

Die dritte Option - die Unterstützung für Spezifikationen und Querydsl - ähnelt den JPA-Kriterien, verwendet jedoch eine flexiblere und bequemere API. Dies macht den gesamten Vorgang viel lesbarer und wiederverwendbarer. Die Vorteile dieser API werden bei der Bearbeitung einer großen Anzahl fester Abfragen deutlicher, da wir diese möglicherweise durch eine geringere Anzahl wiederverwendbarer Blöcke präziser ausdrücken können.

Diese letzte Option hat den Nachteil, dass sie entweder XML umfasst oder die Domänenklasse mit den Abfragen belastet.

3.1. Automatische benutzerdefinierte Abfragen

Wenn Spring Data eine neue Repository- Implementierung erstellt, analysiert es alle von den Schnittstellen definierten Methoden und versucht, automatisch Abfragen aus den Methodennamen zu generieren . Dies hat zwar einige Einschränkungen, ist jedoch eine sehr leistungsstarke und elegante Möglichkeit, neue benutzerdefinierte Zugriffsmethoden mit sehr geringem Aufwand zu definieren.

Schauen wir uns ein Beispiel: wenn das Unternehmen einen hat Namen Feld (und die Java Bean Standard getName und setName Methoden), werden wir das definieren findByName Methode in der DAO - Schnittstelle ; Dadurch wird automatisch die richtige Abfrage generiert:

public interface IFooDAO extends JpaRepository { Foo findByName(String name); }

Dies ist ein relativ einfaches Beispiel. Der Mechanismus zur Erstellung von Abfragen unterstützt einen viel größeren Satz von Schlüsselwörtern.

Falls der Parser die Eigenschaft nicht mit dem Domänenobjektfeld abgleichen kann, wird die folgende Ausnahme angezeigt:

java.lang.IllegalArgumentException: No property nam found for type class com.baeldung.spring.data.persistence.model.Foo

3.2. Manuelle benutzerdefinierte Abfragen

Schauen wir uns nun eine benutzerdefinierte Abfrage an, die wir über die Annotation @Query definieren :

@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)") Foo retrieveByName(@Param("name") String name);

Für eine noch genauere Kontrolle über die Erstellung von Abfragen, z. B. die Verwendung benannter Parameter oder das Ändern vorhandener Abfragen, ist die Referenz ein guter Ausgangspunkt.

4. Transaktionskonfiguration

Die tatsächliche Implementierung des von Spring verwalteten DAO ist in der Tat verborgen, da wir nicht direkt damit arbeiten. Dies ist jedoch eine recht einfache Implementierung - das SimpleJpaRepository - die die Transaktionssemantik mithilfe von Anmerkungen definiert .

Dies verwendet expliziter eine schreibgeschützte @ Transactional- Annotation auf Klassenebene, die dann für die nicht schreibgeschützten Methoden überschrieben wird. Der Rest der Transaktionssemantik ist Standard, kann jedoch pro Methode leicht manuell überschrieben werden.

4.1. Ausnahme Übersetzung ist lebendig und gut

Die Frage ist nun, ob Spring Data JPA nicht von den alten ORM-Vorlagen ( JpaTemplate , HibernateTemplate ) abhängt und seit Spring 5 entfernt wurde. Werden unsere JPA-Ausnahmen weiterhin in die DataAccessException- Hierarchie von Spring übersetzt ?

Natürlich sind wir - Ausnahmeübersetzung wird weiterhin durch die Verwendung der Annotation @Repository auf dem DAO aktiviert . Diese Annotation ermöglicht es einem Spring Bean-Postprozessor, alle @ Repository- Beans mit allen im Container gefundenen PersistenceExceptionTranslator- Instanzen zu beraten und wie zuvor eine Ausnahmeübersetzung bereitzustellen.

Lassen Sie uns die Ausnahmeübersetzung mit einem Integrationstest überprüfen:

@Test(expected = DataIntegrityViolationException.class) public void givenFooHasNoName_whenInvalidEntityIsCreated_thenDataException() { service.create(new Foo()); }

Beachten Sie, dass die Ausnahmeübersetzung über Proxys erfolgt. Damit Spring Proxys für die DAO-Klassen erstellen kann, dürfen diese nicht als endgültig deklariert werden .

5. Spring Data JPA-Repository-Konfiguration

Um die Unterstützung für das Spring JPA-Repository zu aktivieren, können Sie die Annotation @EnableJpaRepositories verwenden und das Paket angeben, das die DAO-Schnittstellen enthält:

@EnableJpaRepositories(basePackages = "com.baeldung.spring.data.persistence.repository") public class PersistenceConfig { ... }

Mit einer XML-Konfiguration können wir dasselbe tun:

6. Java- oder XML-Konfiguration

Wir haben bereits in einem früheren Artikel ausführlich erläutert, wie JPA im Frühjahr konfiguriert wird. Spring Data nutzt auch die Unterstützung von Spring für die JPA @ PersistenceContext- Annotation. Damit wird der EntityManager mit der Spring Factory Bean verbunden, die für die Erstellung der eigentlichen DAO-Implementierungen verantwortlich ist - JpaRepositoryFactoryBean .

Zusätzlich zu der bereits besprochenen Konfiguration müssen wir auch die Spring Data XML-Konfiguration einbeziehen - wenn wir XML verwenden:

@Configuration @EnableTransactionManagement @ImportResource("classpath*:*springDataConfig.xml") public class PersistenceJPAConfig { ... }

7. Maven-Abhängigkeit

In addition to the Maven configuration for JPA, like in a previous article, we'll add the spring-data-jpa dependency:

 org.springframework.data spring-data-jpa 2.2.7.RELEASE 

8. Using Spring Boot

We can also use the Spring Boot Starter Data JPA dependency that will automatically configure the DataSource for us.

We also need to make sure that the database we want to use is present in the classpath. In our example, we've added the H2 in-memory database:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.6.RELEASE   com.h2database h2 1.4.200 

As a result, just by doing these dependencies, our application is up and running and we can use it for other database operations.

The explicit configuration for a standard Spring application is now included as part of Spring Boot auto-configuration.

We can, of course, modify the auto-configuration by adding our customized explicit configuration.

Spring Boot provides an easy way to do this using properties in the application.properties file:

spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 spring.datasource.username=sa spring.datasource.password=sa

In this example, we've changed the connection URL and credentials.

9. Conclusion

This article covered the configuration and implementation of the persistence layer with Spring 5, JPA 2, and Spring Data JPA (part of the Spring Data umbrella project), using both XML and Java-based configuration.

We discussed ways to define more advanced custom queries, as well as transactional semantics, and a configuration with the new jpa namespace. The final result is a new and elegant take on data access with Spring, with almost no actual implementation work.

Die Implementierung dieses Spring Data JPA-Tutorials finden Sie im GitHub-Projekt.