GEDOPLAN
Jakarta EE (Java EE)

JPA und Bean Validation – ein Paar mit verschiedenen Ansichten

Jakarta EE (Java EE)

Bean Validation ist genial – zumindest meistens: Instanzvariablen oder Property-Getter von Domänenobjekten können einfach mittels Annotationen mit Regeln – Constraints – versehen werden, um bspw. auszudrücken, dass ein Feld nicht leer bleiben darf (@NotNull String name) oder bestimmte Wertebereiche nicht verlassen darf (@Min(18) int age).

Geprüft werden die Constraints dann z. B. in JSF-Eingabeformularen oder beim Speichern von JPA-Entities. Zudem ist eine explizite Validierung per API möglich. Da bleiben eigentlich kaum Wünsche offen, wenn da nicht eine recht eigenwillige – man könnte auch sagen “unsinnige” – Regelung in der JPA-Spezifikation zum Grübeln anregen würde:

Die JPA-Spezifikation verlangt von JPA-Providern, dass sie die Validität von in der Datenbank einzutragenden Objekten vor der Speicherung überprüfen, und zwar “upon the
pre-persist, pre-update, and pre-remove lifecycle … events” (Abschnitt 3.6.1 der Spec.).

Die Referenzimplementierung EclipseLink hält sich da auch sklavisch dran, was aber im Falle der Neuanlage eines DB-Eintrags einigermaßen sinnbefreit ist: Wird ein transientes Objekt an EntityManager.persist übergeben, geschieht die Prüfung in diesem Moment und ungültige Objekte werden abgelehnt (via ConstraintViolationException). Ändert man das Objekt in der Folge, aber noch vor dem Commit, wird nicht etwa nochmals geprüft! Dadurch können also (hoffentlich unbewusst) ungültige Daten in die DB gelangen. Auf der sicheren Seite ist man nur, wenn man vor dem Commit explizit EntityManager.flush aufruft. Dann wird nämlich erneut geprüft …

Es kommt aber noch schlimmer: Bean Validation erlaubt auch Constraints auf Properties, die nicht Teil der persistenten View eines JPA-Objektes sind. So könnte z. B. für ein Objekt mit Field Access – bei dem also die Instanzvariablen auf DB-Spalten gemapped werden – eine Methode namens isValid mit Bean Validation Constraintzs versehen sein, um bspw. feldübergreifende Gültigkeitsregeln zu prüfen. EclipseLink ruft diese Validierunsmethode nur dann auf, wenn es zumindest ein BV Constraint auf einem persistenten Feld gibt. Es macht den Eindruck, als hätte da jemand ein bisschen über-optimiert …

Hibernate auf der anderen Seite verhält sich absolut sinnvoll: BV Constraints werden immer vor dem eigentlichen DB-Eintrag geprüft. Das entspricht zwar nicht den Worten der Spezifikation, verhindert aber ungültige Einträge in der DB, was ja wohl der Sinn und Zweck der Angelegenheit ist.

Wenn Sie’s ausprobieren wollen: Unter https://github.com/GEDOPLAN/jpa-bv-demo finden Sie ein Demo-Projekt, das mittels Maven-Profilen zwischen EclipseLink und Hibernate umgeschaltet werden kann.

2 Kommentare. Hinterlasse eine Antwort

  • Hallo,
    vielen Dank für diesen interessanten Blogeintrag.

    Ich würde diesen Blog gern über den RSS-Feed lesen, aber leider ist er veraltet und die neuen Blogeinträge tauchen dort nicht mehr auf. Mir scheint die letzte Aktualisierung ist am
    Tue, 15 Dec 2015 10:09:47 +0000 erfolgt.

    Besten Gruß,
    Tobias

    Antworten

Schreibe einen Kommentar

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

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!