I'd like to know what the best way of exception handling in data access objects is, I'm interested in production quality code.
As an example
public UserDaoImpl implements UserDao{
@PersistenceContext
private EntityManager em;
void save(User user){
em.persist(user);
}
User getById(long id){
return em.find(User.class,id);
}
}
Let's say that for example I have a RegisterService somewhere where at some point I'd like to save the user to the database. And that each User needs to have a unique email. How do you check that and where does this code go ? Do we check if there's a user with that email already in the save method using queries before persisting? Or does that code go to the service? Or maybe we try to catch some exceptions?
But with exceptions as far as I know we'd never know for sure what happened, we could try to catch a ConstraintViolationException but that doesn't tell us explicitely what happened.
How does it look in a production quality code?