EJB ma koncepcję wyjątków systemowych i wyjątków aplikacji.
Wyjątki w czasie wykonywania, takie jak EntityExistsException
są wyjątkami systemowymi. Spowodują one między innymi wycofanie wszelkich transakcji i odrzucenie (zniszczenie) komponentu EJB instancji EJB. Co najważniejsze dla twojego problemu, zostaną one opakowane w EJBException
.
Nie ma magii w łapaniu tych wyjątków. Dostosowując kod z Petra powyżej,
poniżej zadziała:
Fasola:
@EJB
private DAOBean daoBean;
public void savePerson(Entity e) {
try {
daoBean.save(e);
} catch (EJBException e) {
FacesMessage message = new FacesMessage("entity is already exists.");
FacesContext.getCurrentInstance.addMessage(null, message);
}
}
EJB:
private EntityManager em;
public void save(Entity e) {
em.persist(e);
}
Zwróć uwagę, że możesz pobrać przyczynę wyjątku, aby sprawdzić, czy był to EntityExistsException
lub nie (pominięte powyżej ze względu na zwięzłość).
Ponieważ prawdopodobnie nie musisz niszczyć swojej instancji EJB w tym przypadku, lepszym wzorcem jest zdefiniowanie własnego wyjątku, który dziedziczy po RuntimeException
i ma adnotację @ApplicationException
z rollback
atrybut ustawiony na true.
Np.
@ApplicationException(rollback = true)
public class MyException extends RuntimeException {
public MyException(Throwable cause) {
super(cause);
}
}
Zapakuj swój EntityExistsException
w swoim EJB do tego wyjątku i wrzuć go i złap.
Zdecydowanie radzę NIE w rezultacie użyć kodów błędów lub wartości logicznych sukcesu/porażki. Jest to dobrze znany wzorzec anty, który sprawia, że Twój kod jest niewiarygodnie podatny na błędy.