来自持久层的异常不会命中托管 bean 中的 catch 块

Exception from persistence layer does not hit catch block in managed bean

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

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

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

小脸:

    <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 我坚持我的对象的调用。

我读过这个: Better Exception Handling in JPA

老实说,我发现处理一个简单的异常有点复杂。

谁能解释一下这是怎么回事?是不是线程问题?

我的配置: TOMEE 7 with/Openjpa 2.4/myfaces 2.2.8 JRE 1.8

我遇到了类似的问题,经过几个小时的思考,我发现了实际发生的事情。

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

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

要做的事情:

  1. 检查休眠是否覆盖了你的异常

  2. 在你的事务中处理休眠异常(我做了回滚处理)

  3. 确保自定义应用异常被抛出一直到视图层。