Не используйте логические флаги (или перечисления), чтобы указать исключительные результаты.Используйте исключения для этого.Вам нужно только добавить некоторую логику, к какому виду исключения для конкретной реализации JPA относится PersistenceException
, а затем повторно выбросить его как ваше конкретное бизнес-исключение, например, пользовательское public class DuplicateKeyException extends PersistenceException
.
Например, в вашей бизнес-службереализация
public void register(User user, Person person) throws PersistenceException, DuplicateKeyException {
try {
em.persist(user);
person.setUser(user);
em.persist(person);
}
catch (PersistenceException e) {
if (Exceptions.is(e, ConstraintViolationException.class)) {
throw new DuplicateKeyException(e);
}
else {
throw e;
}
}
}
с помощью этого метода в служебном классе Exceptions
:
public static <T extends Throwable> boolean is(Throwable exception, Class<T> type) {
for (;exception != null; exception = exception.getCause()) {
if (type.isInstance(exception)) {
return true;
}
}
return false;
}
, который вы затем обрабатываете на стороне контроллера:
public String register() {
try {
personEAO.register(personb.getUser(), personb.getPerson());
Messages.addGlobalInfo("user.register.success");
return "success";
}
catch (DuplicateKeyException e) {
logger.log(e); // If necessary.
Messages.addGlobalError("user.register.error.duplicate");
return "failure";
}
}
The Messages.addGlobalXxx()
может добавить глобальный FacesMessage
к контексту, как показано ниже:
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_INFO, someBundle.getString(key), null));
OmniFaces имеет подобный класс , который может помочь вам здесь.
Такое глобальное сообщение будет только отображаться в
<h:messages globalOnly="true" />