我已经四处寻找这个问题的帮助,但实际上我不知道问题出在哪里,所以我不知道该找什么。
简单来说: - 我有一个表单,它使用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
答案 0 :(得分:0)
我有类似的问题,经过数小时的打破,我发现了实际发生的事情。
当我的DAO出现异常并且我从DAO抛出自定义应用程序异常时,我意识到当仍然在我的事务范围内时,自定义异常被hibernate的异常覆盖,因此我的视图层无法捕获应用程序的自定义异常
我所要做的就是在事务中处理异常和rollBack事务。 (这是一个插入操作)
要做的事情:
检查hibernate是否覆盖了您的例外
在您的交易中处理hibernate异常(我做了一个回滚句柄)
确保自定义应用程序例外被抛出一直到视图层。