I am fairly new to JPA and want to find best practices when handling persistence exceptions from JPA for things like say, unique constraint violations which can be addressed by the user. There are tons of examples on how to write JPA apps, but almost nothing on how to hand exceptions kicked out by them. :/
For example registering a user, the person enters an email address that is already in active use by the system and gets a constraint violation:
try {
em.persist(credentials);
} catch (javax.persistence.PersistenceException ex) {
which produces this error when a duplicate email is added:
WARNING: SQL Error: 0, SQLState: 23505
SEVERE: ERROR: duplicate key value violates unique constraint "EMAIL_UQ_IDX"
Detail: Key (email)=([email protected]) already exists.
How can I get a meaningful answer back to the user? For example something like: Oops looks like someone is using that email address already, are you sure you haven't registered before? Is there a facility built in to parse this or will I need to run regexes against the exception message in a (possibly a series of) if statement(s)?
And what about if it is caught on the business tier... what are best practices for kicking it up to the presentation tier... like I said before, so that a 'nice' message can be provided for the user.
Added for clarity: Just so people know, I had, have, and am still looking at all the different types of persistence exceptions, and here is some of the research I've been doing I didn't include with the "try statement" example I included above:
try {
em.persist(credentials);
} catch (javax.persistence.PersistenceException ex) {
System.out.println("EXCEPTION CLASS NAME: " + ex.getClass().getName().toString());
System.out.println("THROWABLE CLASS NAME: " + ex.getCause().getClass().getName().toString());
Throwable th = ex.getCause();
System.out.println("THROWABLE INFO: " + th.getCause().toString());
Logger.getLogger(CredentialsControllerImpl.class
.getName()).log(Level.INFO, "Credentials Controller "
+ "persistence exception "
+ "EXCEPTION STRING: {0}", ex.toString());
Logger.getLogger(CredentialsControllerImpl.class
.getName()).log(Level.INFO, "Credentials Controller "
+ "persistence exception "
+ "THROWABLE MESSAGE: {0}", th.getMessage());
Logger.getLogger(CredentialsControllerImpl.class
.getName()).log(Level.INFO, "Credentials Controller "
+ "persistence exceptions "
+ "THROWABLE STRING: {0}", th.toString());
}
:)