10 January 2016
Can exceptions be friendly? :-)
I was working on a web site today and while saving an entity I violated a unique constraint on its table. Nothing out of the ordinary, but it has to be handled, some kind of a message must be displayed to the user. And since this can potentially happen on any service method I wanted a unified approach to handling it.
By default Spring simply translates the exception to its hierarchy and in the end we get a DataIntegrityViolationException, but its message is not something that can be shown to the user.
That translation process got me thinking, why not use it to deliver a user friendly message instead. I knew it was configured by PersistenceExceptionTranslationPostProcessor bean so I started digging trough the code from there. Spring being as configurable as it is I expected to find a way to use the translation process to translate SQLExceptions to my own exception with a better message. And of course, Spring provides a way, just implement a PersistenceExceptionTranslator bean and it's done...
Unfortunately it wasn't that simple :-)
It seems that in fact defining PersistenceExceptionTranslationPostProcessor bean is not needed when using JpaTransactionManager , not only is it not needed, but it makes no difference, translation is always on, it's done by JpaTransactionManager itself, completely separate from anything PersistenceExceptionTranslationPostProcessor sets up.
Additionally while going through the translation code I found out that all PersistenceExceptionTranslators registered in a context are at one point loaded in a list, in an arbitrary order, and basically first one found that is capable of translating the exception does it. There is no way to set priority that would allow me to consistently translate an exception before it is translated by default translators.
So there had to be another way...
I decided to do it like JpaTransactionManager does it, extend it and override the doCommit method, catch DataIntegrityViolationExceptions and check whether they are the ones I'm interested in and for those throw a new constraint with a user friendly message retrieved from a ResourceBundle based on a constraint name. As the constraint name is included in the message thrown by the PostgreSQL JDBC driver it's easy to determine exactly which constraint was violated.
This is what I came up with. It works for PostgreSQL only, and relies on messages returned by the server, hopefully they won't change any time soon. I have checked it on unique, foreign key and check constraints.
Btw. a quick way to get a list of constraints in your database: select conname from pg_constraint
30 December 2015
Looking at the logs it seems that some people still use my old OpenWRT build customized for Siemens SX763 with VOIP customizations for Iskon. Since then I've changed my ISP and router so I've stopped playing with this, but I'll keep the firmware and package repository online for any existing users. If you are just picking a new firmware for your router I recommend to get a newer one from this thread on PC Ekspert.Original post in Croatian:
Build je revizija 36088 iz SVN-a uz neke manje promjene i dodatke:
Za detalje oko instalacije i ostala pitanja bacite pogled na ovaj thread.
30 December 2015
Welcome to the party, leave your coat on the hanger and grab a drink...
Older posts are available in the archive.