Spring mit einer Webanwendung mit JPA und Validierung (Tutorial)

Der Service der Fahrerverwaltung

Dieser Beitrag ist Teil einer (Tutorial-) Serie über die Einführung in das Spring Framework und beschreibt das Erstellen einer Webanwendung mit der Verwendung von JPA und Validierung im Spring Framework.

Die Struktur des Projektes

Dieses Beispiel baut auf dem vorherigem Beispiel Spring mit einer einfachen Webanwendung und dem Beispiel Spring mit JPA und Hibernate jeweils in der Version 1.x auf. Die verwendeten Frameworks und Werkzeuge sind hier beschrieben. In diesem Beispiel werden die folgenden Technologien des Spring Frameworks vorgestellt:

  • Die Validierung mit dem JSR 303.
  • Einen eigenen Validator mit Meldungen erstellen.
  • Formulare mit Spring Framework MVC erstellen.
  • Das Erstellen eines JUnit Test mit Spring Test, Hamcrest und Mockito.

In der folgenden Bildergalerie sind die benötigten Bibliotheken pro Eclipse Projekt dargestellt und die Erweiterung, die am Web Projekt nötig sind.

Die Literaturempfehlungen für dieses Beispiel

Die Verbindung zwischen den Modulen herstellen

Zwischen dem Web Projekt und dem Projekt mit dem Service der Fahrerverwaltung muss eine Verbindung geschaffen werden. Dazu muss in der Konfiguration des Web-Projektes die Verweise auf die Konfiguration der fachlichen Spring Beans erweitert werden.

Die Anpassungen an der Fahrerverwaltung

Zusätzlich wird noch in der XML Konfiguration für die Datenbankeinstellungen ein Transformer (Spring Bean Post Prozessor) für die Ausnahme javax.persistence.PersistenceException definiert. Dieser Transformer wandelt die JPA-spezifischen Ausnahmen zu Spring Framework Ausnahmen vom Typ org.springframework.dao.DataAccessException um.

Die Änderung am generischen DAO

Im Initialisierer des AbstractGenericDAO<Entity, PrimaryKey> werden die parametrisierten Typen der generischen Klasse ausgewertet. Wurde aber durch Spezialisierung die Anzahl der parametrisierten Typen reduziert, dann muss die Methode getClass().getGenericSuperclass() nicht unbedingt einen ParameterizedType zurück liefern. Daher muss die Vererbungshierarchie durchgegangen werden, bis wieder zwei parametrisierte Typen vorhanden sind.

Die Validierung mit JSR 303

Der Service der Fahrerverwaltung soll um eine Validierung nach dem Standard Bean Validation JSR 303 erweitert werden. Zunächst wird eine eigene Erweiterung der Validierung vorgenommen. Dazu wird die Annotation @NotNullOrBlank im Eclipse-Projekt test-spring-jpa definiert.

  • In der Zeile 27 wird der Validierer definiert, der die eigentlichen Überprüfungen vornimmt.
  • In der Zeile 29 wird die Standardmeldung definiert. Die Meldung selber ist in einer Properties-Datei ausgelagert.

Die Properties-Datei für die englischen Meldungen.

Die Properties-Datei für die deutschen Meldungen.

Die folgende Klasse definiert den eigentlichen Validierer, der die Überprüfung durchführt.

  • In der Zeile 20 wird der Validierer initialisiert und in der Zeile 30 befindet sich die Überprüfung.

Nun muss noch die Validierung nach dem JSR 303 unter dem Spring Framework aktiviert werden. Dazu wird eine XML Konfiguration für die zentrale Validation erstellt.

Die Validierung soll für die Entität Fahrer im Services der Fahrerverwaltung verwendet werden.

  • In den Zeilen 45 und 51 an den Attributen werden die Annotationen bzw. Anweisungen für die Validierung angegeben.

Der vollständige Service der Fahrerverwaltung

Im folgenden Bild wird der vollständige Service in einem UML-Klassendiagramm dargestellt.

Der Service der Fahrerverwaltung (© Frank Rahn)

Die Anpassungen an der Webanwendung

Das Eclipse-Projekt test-spring-web muss, um die Oberfläche für die Fahrerverwaltung erweitert werden. Dazu wird in der Startseite ein zusätzlicher Link auf den Fahrerverwaltung hinzugefügt.

Die erste Maske der Fahrerverwaltung listet alle Fahrer auf.

  • In den Zeilen 12 bis 18 werden mögliche Hinweise oder Fehler angezeigt.
  • In den Zeilen 26 bis 28 wird für jeden Fahrer ein Links mit der Id des Fahreres auf die Bearbeitungsseite erzeugt und in Zeile 33 verwendet.

Die folgende Oberfläche ist für die Bearbeitung bzw. Erzeugung eines Fahrer zuständig – Bearbeitungsmaske.

  • In der Zeile 14 wird das Formular definiert. Das Attribut commandName verweist dabei auf ein Model.

Für die Oberfläche der Fahrerverwaltung wird ein Controller erstellt.

  • In der Zeile 42 wird eine Bearbeitungsmethode erstellt, die bei jedem Request durchgeführt wird und sicherstellt, das eine Instanz des Fahrer geladen oder erzeugt wird.

Die XML Konfiguration des Spring Servlets wird um einen Interceptor auf die Fahrerverwaltung erweitert. Dieser Interceptor sorgt dafür, das im DriversController in Zeile 105 die Autos lazy geladen werden können. Normalerweise wird der EntityManager beim Commit, auf die Transaktion, geschlossen und beim Zugriff auf Attribute der Entität, die Lazy geladen werden, wird die Ausnahme org.hibernate.LazyInitializationException geworfen. Dieser Interceptor hält den EntityManager offen solange bis der Request abgearbeitet ist.

Die neuen Masken

In folgender Bildgalerie werden die neuen Masken im Browser dargestellt.

Der Unit Test

Für den DriversController wird ein JUnit Test DriversControllerTest erstellt. Dazu muss zunächst eine XML Konfiguration erstellt werden.

  • In Zeile 15 wird der Fahrerservice über das Mocking-Framework Mockito erzeugt.

Als nächstes wird der eigentliche Test erstellt.

  • In den Zeilen 68, 81, 92 und 113 bis 115 werden über das Mocking Framework given(drivers.methode()) die Rückgaben .willReturn(object) des Fahrerservices bestimmt.
  • In den Zeilen 123 und 132 wird die Anzahl der Aufrufe der Methode drivers.getDrivers() überprüft.

In Eclipse sieht das Ergebnis des JUnit Tests wie folgt aus:

Die Erfolgsmeldung von JUnit (© Frank Rahn)

Der Quellcode und Download des Beispiels

Den Quellcode ansehen bei GitHub:
Spring mit JPA und Hibernate
Spring mit einer einfachen Webanwendung

Der Download einer ZIP-Datei von GitHub:
Spring mit JPA und Hibernate
Spring mit einer einfachen Webanwendung

Update am 28.09.2012

Es wurden folgende Änderungen an allen Projekten vorgenommen.

  1. Die Projekte wurden aus meinem lokalen Apache Subversion Repository in meine öffentlichen GitHub Repositories verschoben.
  2. Die folgenden typischen Anpassungen an Git wurden an allen Projekten durchgeführt.
    • .directory gelöscht
    • .gitignore hinzugefügt
    • README.md hinzugefügt
    • COPYRIGHT.md hinzugefügt
    • In jedem Repository wurde für jeden Beitrag der Serie ein Branch angelegt.
      • develop-spring-an-einem-einfachen-beispiel
      • develop-spring-mit-aop
      • develop-spring-mit-jpa-und-hibernate
      • develop-spring-mit-einer-einfachen-webanwendung
      • develop-spring-mit-einer-webanwendung-mit-jpa-und-validierung
      • develop-spring-security-mit-einer-webanwendung
      • develop-spring-mit-restful-webservice

Updates von 06.10.2012 bis zum 14.10.2012

Es wurden folgende Änderungen an allen Projekten vorgenommen.

  1. Aktualisierung des OpenJDK auf die Version 1.7.0.
  2. Aktualisierung der Entwicklungsumgebung Eclipse auf die Version 4.2.1.
    Die benötigten Plugins aus dem Eclipse Marketplace:

  3. Aktualisierung der Datei pom.xml:
    • Anpassungen an die OpenJDK Version
    • GitHub Einträge (SCM und URL) hinzugefügt
    • Aktualisierung der Libraries auf aktuellerer Versionen (z. B. Spring Version 3.1.2.RELEASE, Hibernate Version 4.1.7.Final, JUnit Version 4.10, mockito Version 1.9.0, …)
      Die genaueren Versionen bitte aus den jeweiligen pom.xml auf GitHub entnehmen.

Frank Rahn

Frank Rahn ist Softwarearchitekt. Er unterstützt bei der Konzeption von Softwarearchitekturen mit Java-Technologie. Folge Sie ihm auf Facebook, Twitter oder Google+.

Benötigen Sie Unterstützung? Kontaktieren Sie ihn.

Hat Ihnen dieser Beitrag gefallen? Wir würden uns über Ihren Kommentar freuen! Bitte verwenden Sie Ihren bürgerlichen Namen und eine E-Mail-Adresse mit Gravatar.

Letzte Artikel von Frank Rahn (Alle anzeigen)

0 Kommentare

Dein Kommentar

Want to join the discussion?
Feel free to contribute!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.