Bonjour,
Avant tout, j'ai hésité sur le bon forum où poser cette question : JPA ? Spring ? J2EE ??
En effet, elle touche les couches Controller/Service/Dao...
Bref, j'espère que je suis à peu près au bon endroit.
Ma situation :
- Couche Application (web) gérée par Seam/JSF
- Couche Service gérée par Spring
- Couche Dao gérée par Spring/JPA
Ma question : comment gérer les exceptions JPA proprement ?
Exemple :
- j'ai une "action" Seam pour mettre à jour une entité (ex: Pays) sur laquelle j'ai une contrainte d'unicité (ex: le code du pays doit être unique)
- je test l'insertion d'un Pays dont le code est déjà présent en base
- j'utilise @Transactional sur la méthode du service.
Mon problème :
- quand le Dao fait l'update, aucune exception n'est levée : car l'ordre est mis de côté en attendant le prochain flush
- je sors du Dao, mon Service prends la main, mais la méthode de mise à jour du Pays dans la couche service ne lève pas non plus d'exception : elle ne fait qu'appeler le Dao
- en revanche, dans mon action Seam, je récupère une exception de type PersistenceException : en effet, mon service est exécutée dans le cadre d'une transaction (@Transactional sur la méthode service je le rappelle)
Ce que je veux :
- laisser l'utilisateur sur la même page, avec un message d'erreur lui indiquant que le cas d'erreur présent est issu (fonctionnellement parlant) d'une valeur déjà existante en base
- pour cela, j'ai besoin de traduire l'exception...
1. A la base, c'est uniquement une fois de retour dans l'action que je récupère l'exception : je trouve pas très propre de traiter l'exception à ce niveau là, car cela lierait fortement les couches APPLICATION et DAO
--> comment faire ?? avec le @Transactional, le flush sera provoqué forcément en dehors de mes méthodes de SERVICE et DAO.
2. Je pourrais provoquer un flush dans la méthode DAO
Dans ce cas, j'aurais bien la possibilité de traiter l'exception PersistenceException au niveau DAO, mais est-ce vraiment propre de faire ça ?
3. J'ai aussi tenté la traduction des exceptions par Spring (via PersistenceExceptionTranslationPostProcessor) mais la traduction se produit forcément à la sortie de la méthode SERVICE et donc je me retrouve quand même à traiter une exception de la couche DAO dans la couche APPLI (même si elle a été traduite en DataAccessException).
Quelles sont les bonnes pratiques svp ?
Partager