O EJB tem o conceito de exceções do sistema e exceções do aplicativo.
Exceções de tempo de execução, como
EntityExistsException
são exceções do sistema. Isso, entre outros, fará com que qualquer transação seja revertida e fará com que o bean de instância EJB seja descartado (destruído). Mais importante para o seu problema, eles serão envolvidos em um EJBException
. Não há mágica em torno da captura dessas exceções. Ajustando o código do Petr acima,
o seguinte funcionará:
Feijão de apoio:
@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);
}
Observe que você pode recuperar a causa da exceção para ver se foi uma
EntityExistsException
ou não (omitido acima por questões de brevidade). Como você provavelmente não precisa destruir sua instância EJB para este caso, um padrão melhor é definir sua própria exceção que herda de um
RuntimeException
e é anotado com o @ApplicationException
com o rollback
atributo definido como verdadeiro. Por exemplo.
@ApplicationException(rollback = true)
public class MyException extends RuntimeException {
public MyException(Throwable cause) {
super(cause);
}
}
Envolva sua
EntityExistsException
em seu EJB para esta exceção e jogue e capture-o. Eu recomendo fortemente que você NÃO para usar códigos de erro ou sucesso/falha booleano como resultado. Este é um anti padrão bem conhecido e torna seu código incrivelmente propenso a erros.