Set<DogValidationException> exceptions = new HashSet<DogValidationException>();
boolean retry;
do {
retry = false;
try {
dog.validate(exceptions);
} catch (DogValidationException e) {
exceptions.add(e);
retry = true;
}
} while (retry);
if(exceptions.isEmpty()) {
//dogDAO.beginTransaction();
commit transaction dogDAO.save(dog);
dogDAO.commitAndCloseTransaction();
} else {
// notify user to fix the problems
}
The problem here is that the validation process, to get all errors, would require to skip already found exceptions. The above could work, but this is a clear misuse of exceptions. The kind of validation you were asked for should take place before the database is touched. So there is no need to roll back anything. And, the results of the validation are likely to be validation errors (hopefully zero, though).
Set<Problem> validationResults = dog.validate();
if(validationResults.isEmpty()) {
//dogDAO.beginTransaction();
commit transaction dogDAO.save(dog);
dogDAO.commitAndCloseTransaction();
} else {
// notify user to fix the problems
}
Why? There are tons of reasons, and the most reasons have been pointed out in the other responses. To put it simple: It is much simpler to read and understand by others. Second, do you want to show the user stack traces to explain him he set up his dog
wrongly?
If, during the commit in the second example, still an error arises, even though your validator validated the dog
with zero issues, then throwing an exception is the right thing. Like: No database connection, the database entry has been modified by someone else meanwhile, or that like.