持久层的异常不会触发托管bean中的catch块

时间:2015-05-19 20:56:04

标签: jsf jpa exception-handling

我已经四处寻找这个问题的帮助,但实际上我不知道问题出在哪里,所以我不知道该找什么。

简单来说: - 我有一个表单,它使用JPA在JSF生成的Ajax中保存DB中的对象。 - 当存在PersistenceException时,我想处理它并向用户发送消息。

在我的DAO中,我捕获PersistenceException并向我的Backing Bean抛出一个新的自定义DAOException,以便向视图添加FacesMessage。

Facelet:

    <h:outputLabel for="codePF" styleClass="control-label">Code PF <span class="requis">*</span>
                    </h:outputLabel>
                    <h:inputText id="codePF" value="#{gestionDemandes.demande.motCle}" required="true" size="20" maxlength="20"  styleClass="form-control">
                        <f:ajax event="blur" render="codePFMessage" />
                    </h:inputText>
                    <h:message id="codePFMessage" for="codePF" errorClass="erreur" />
                    <br />

                    <h:messages globalOnly="true" infoClass="info" />

                    <h:commandButton id="boutonDemande" value="Inscription" action="#{gestionDemandes.creerDemande()}" styleClass="btn btn-primary">
                        <f:ajax execute="@form" render="@form" />
                        <h:message id="boutonDemandeMessage" for="boutonDemande" errorClass="bg-danger"  infoClass="bg-success"  />
                    </h:commandButton>
                    <br />
                </h:form>

支持Bean:

   @ManagedBean
   @RequestScoped
public class GestionDemandes implements Serializable {
private static final String ERREUR_AJOUT = "Erreur de création de la demande";
private static final String SUCCES = "Demande ajoutée !";

// Injection de notre EJB (Session Bean Stateless)
@EJB
private DAODemande daoDemande;
// Demande utilisée par le formulaire de création de demandes
public void creerDemande() {

FacesMessage message;
try {
    daoDemande.creer(demande);
} catch (DAOException dao) {
    message = new FacesMessage(FacesMessage.SEVERITY_ERROR, ERREUR_AJOUT,
        dao.getMessage());
    FacesContext.getCurrentInstance().addMessage(null, message);
    return;
}
message = new FacesMessage(SUCCES);
FacesContext.getCurrentInstance().addMessage(null, message);
}

DAO:

@Stateless
public class DAODemande {
// Injection du manager
@PersistenceContext(unitName = "gamabddactuelle_PU")
private EntityManager em;

// Enregistrement d'un nouvel utilisateur
public void creer(Demande demande) throws DAOException {

demande.setIdDemande(demande.getIdClientDemande());
try {
    em.persist(demande);
    em.flush();
} catch (PersistenceException e) {
    throw new DAOException(e.getCause());
}
}

首先,我必须在DAO中添加em.flush(),否则我甚至不会捕获PersistenceException。

然后当我抛出DAOException时,我不会在我的Backing Bean中捕获它。 似乎DAOException抛出了另一个线程,而不是Ajax Call,我坚持我的Object。

我读到了这个: Better Exception Handling in JPA

老实说,我发现处理一个简单的例外事件有点复杂。

有人可以解释这里发生了什么吗?这是线程问题吗?

我的Conf: TOMEE 7与/ Openjpa 2.4 / myfaces 2.2.8 JRE 1.8

1 个答案:

答案 0 :(得分:0)

我有类似的问题,经过数小时的打破,我发现了实际发生的事情。

当我的DAO出现异常并且我从DAO抛出自定义应用程序异常时,我意识到当仍然在我的事务范围内时,自定义异常被hibernate的异常覆盖,因此我的视图层无法捕获应用程序的自定义异常

我所要做的就是在事务中处理异常和rollBack事务。 (这是一个插入操作)

要做的事情:

  1. 检查hibernate是否覆盖了您的例外

  2. 在您的交易中处理hibernate异常(我做了一个回滚句柄)

  3. 确保自定义应用程序例外被抛出一直到视图层。