# Exception-Handling in Hibernate/JPA



## -MacNuke- (30. Okt 2009)

Hallo.

Frage ist eigentlich recht kurz: Wie fange ich in JPA/Hibernate die Exceptions korrekt ab?

Bisher hab ich es so (pseudo-Code):

```
try {
   starteSession();
   aendereEtwas();
   commit();
} catch (PersistenceException ex) {
   // Fehlermeldung
}
```

Beim Commit fliegt ja nun eine Exception. Ich habe auch in diversen Tutorials gelesen, dass die Persistence-Exception eigentlich alle möglichen Exceptions beinhaltet. Dies scheint aber nicht der Fall zu sein. Denn wenn durch eine Eingabe z.B. ein Constraint in der Datenbank verletzt wird, stürzt die Anwendung trotzdem ab mit:


```
org.hibernate.exception.ConstraintViolationException: could not update:
....
Caused by: org.postgresql.util.PSQLException: FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint
```

Ich muss muss diesen Fall dann so fangen:

```
try {
   starteSession();
   aendereEtwas();
   commit();
} catch (PersistenceException ex) {
   // Fehlermeldung
} catch (ConstraintViolationException ex) {
   // Fehlermeldung
}
```

Diese ConstraintViolationException ist natürlich aus Hibernate und somit habe ich eine direkte Abhängigkeit von Hibernate im Code, was ich momentan nicht will.

Übersehe ich da irgendetwas, oder habe ich etwas falsch verstanden? Wenn ja, was muss ich denn alles an Exceptions fangen, damit bei einer Fehleingabe nicht gleich das Programm "abstürzt"?

Danke


----------



## byte (30. Okt 2009)

Hibernate wirft Hibernate Exceptions. Wenn Du diese Abhängigkeiten nicht in Deinem Code haben willst, bleibt Dir nichts anderes übrig, als RuntimeException zu fangen. Sinn macht das aber keinen. Zumal eine ConstraintViolationException eh ein nicht behandelbarer Programmierfehler ist.

Im Grunde kannst Du einfach Throwable fangen und dann ein Rollback machen + die Exception loggen. Mehr kann man eh nicht behandeln in so nem Fall, da DB-Exceptions idR Programmierfehler sind.


Es gibt allerdings auch Hibernate Exceptions wie Optimistic Locking Failures, wo es durchaus Sinn macht, die zu behandeln. Da wüsste ich nicht, wie man das ohne eine Abhängigkeit zu dieser Exception Klasse lösen könnte.
Eine Lösung wäre Spring, denn Spring liefert eine sehr gute Exception Wrapper Hierarchie für Persistenzfehler (DataAccessException), ist auch Vendor Unabhängig, funktioniert also für alle JPA Implementierungen. Allerdings willst Du wahrscheinlich auch keine Spring Abhängigkeit, nehme ich an!?


----------



## maki (30. Okt 2009)

> Mehr kann man eh nicht behandeln in so nem Fall, da DB-Exceptions idR Programmierfehler sind.


in der Regel shon, aber diesmal wohl nicht:

```
FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint
```
Wenn der User einen Wert angeben darf, der in der DB nicht doppelt sein darf, könnte man ihm die Möglichekit bieten einen anderen zu wählen, dazu müsste man aber wissen ob eine ConstraintViolationException geworfen wurde deren Message auf so einen Fehler hinweist.

Ist nicht leicht diese Thema imho...


----------



## byte (30. Okt 2009)

Oh richtig. Da war ich etwas voreilig.


----------



## -MacNuke- (30. Okt 2009)

byte hat gesagt.:


> Sinn macht das aber keinen. Zumal eine ConstraintViolationException eh ein nicht behandelbarer Programmierfehler ist. Mehr kann man eh nicht behandeln in so nem Fall, da DB-Exceptions idR Programmierfehler sind.



Ahja... und wie verwaltest du Werte die der Nutzer frei eingeben darf/soll, die aber Eindeutig sein müssen?

Und das ich kein Interesse daran habe, Hibernate-Abhängigkeiten im Code zu haben, liegt schlicht daran, dass ich noch gar nicht weiß, ob ich bei Hibernate bleiben will. Ich hoffe DAS Thema hat sich damit jetzt erst mal erledigt...


----------



## -MacNuke- (30. Okt 2009)

Ich sehe auch gerade, dass Hibernate zuerst die Constraint-Exception schmeißt und anschließend noch mal eine Constraint-Exception verpackt in einer javax.persistence.RollbackException...

Naja, mal weiter suchen, wie man das behandelt.


----------



## byte (31. Okt 2009)

-MacNuke- hat gesagt.:


> Ahja... und wie verwaltest du Werte die der Nutzer frei eingeben darf/soll, die aber Eindeutig sein müssen?
> 
> Und das ich kein Interesse daran habe, Hibernate-Abhängigkeiten im Code zu haben, liegt schlicht daran, dass ich noch gar nicht weiß, ob ich bei Hibernate bleiben will. Ich hoffe DAS Thema hat sich damit jetzt erst mal erledigt...



Keine Ahnung warum Du jetzt so aggressiv reagierst. Nächstes Mal überleg ich wohl zweimal ob ich versuche Dir bei Deinen Problemen zu helfen... :autsch:


----------



## -MacNuke- (1. Nov 2009)

byte hat gesagt.:


> Keine Ahnung warum Du jetzt so aggressiv reagierst.



Weil du einem Unfähigkeit unterstellst, nicht wirklich auf die Frage eingehst, wünsche missachtest, pampig antwortest...



byte hat gesagt.:


> Nächstes Mal überleg ich wohl zweimal ob ich versuche Dir bei Deinen Problemen zu helfen... :autsch:



Hast du mir sowieso noch nie wirklich. Das letzte woran ich mich bei dir erinnere, dass du behauptest, Hibternate würde keine Exceptions verschlucken usw. und anschließend nicht mehr darauf reagierst... geholfen hast du da auch nicht, außer zu behaupten, dass Hibernate es nicht machen würde... von daher... überleg ruhig zweimal...


----------



## byte (2. Nov 2009)

-MacNuke- hat gesagt.:


> Hast du mir sowieso noch nie wirklich.



Scheinst ja sehr vergesslich zu sein. Aber gut zu wissen, wie Du so drauf bist. Werds mir merken.


----------



## KSG9|sebastian (9. Nov 2009)

-MacNuke- hat gesagt.:


> Weil du einem Unfähigkeit unterstellst, nicht wirklich auf die Frage eingehst, wünsche missachtest, pampig antwortest...
> 
> 
> 
> Hast du mir sowieso noch nie wirklich. Das letzte woran ich mich bei dir erinnere, dass du behauptest, Hibternate würde keine Exceptions verschlucken usw. und anschließend nicht mehr darauf reagierst... geholfen hast du da auch nicht, außer zu behaupten, dass Hibernate es nicht machen würde... von daher... überleg ruhig zweimal...



Schalt mal nen Gang runter!

byte hat nur versucht dir zu helfen, wenn du das nicht verstehst kann er doch nix dafür.



Wenn du die spezifischen Exceptions haben willst dann hast du (leider) Abhängigkeiten auf die konkrete Implementierung.
Eine Variante wäre einen "ExceptionHandler" zu schreiben der Abhängig von der JPA-Implementierung ist.
In diesem Handler kannst du dann die Hibernate, EclipseLink us.w..-Exceptions in eigene Exceptions verpacken und werfen.


----------



## Noctarius (10. Nov 2009)

Saubere Exception-Kapselung: externes Modul (Projekt mit Abhängigkeiten) + AOP + Exception Wrapping


----------

