how do you handle and parse JPA persistence exceptions to provide meaningfull message to user
You typically don't use the low-level exceptions to do that.
Instead, you explicitely check that the email is available (using a query), and perist the email only if it doesn't exist.
Sure, there could be a race condition if two threads do the same check in parallel, but it will be extremely rare, and the database constraint is there to guarantee the uniqueness.
There are subclasses of PersistenceException: EntityExistsException, EntityNotFoundException, NonUniqueResultException, NoResultException, OptimisticLockException, RollbackException, TransactionRequiredException. Source: http://docs.oracle.com/javaee/5/api/javax/persistence/PersistenceException.html
You can use them. Try to check the type of exception or overload an error handling method (which is better). EntityExistsException I think the error you are searching for in the example you gave above. But you should check "if it exists" yourself. That's the best practice.
The SQL Error should never be needed to shown to the user. That error is always for you. Any data related error which needs informing user must be checked manually.
I use J2EE Web Environment. I just forward the request to error.jsp if there's an exception. I also provide an extra object for error.jsp to clarify the information like user can go back, can go which page after error etc. Of course I automated this, I don't like writing redundant code, because it is hard to update. So I just write send the exception and error message to another class in the catch block.
I'm doing something similar in my DB service layer to figure out whether the exception was caused by a conflicting constraint or general DB failure:
try {
....
} catch (final PersistenceException e) {
final Throwable cause = e.getCause();
if (cause instanceof MySQLIntegrityConstraintViolationException) {
throw new ConflictException(cause);
}
throw new ServiceException(e);
}