<f:viewparam> javax.persistence.NoResultException:找不到查询的实体

时间:2015-06-27 18:25:04

标签: jsf jsf-2 viewparams

我有一个网格,用户可以看到他的记录,当他点击一个记录时,它链接到另一个页面,这样他就可以编辑或删除它。

该页面中的记录显示正确,并且如果有任何更改,并且让用户返回网格,它有一个更新记录的按钮。

我正在使用Primefaces的Java 1.8,Netbeans 8.0.2和wildfy 8.2,我的操作系统是UBUNTU。

当我尝试更改某些内容时,页面无效,我在wildfly日志中记录了此记录

  

15:11:16,369 ERROR [org.jboss.as.ejb3](默认任务-19)   javax.ejb.EJBTransactionRolledbackException:找不到查询的实体   15:11:16,371 ERROR [org.jboss.as.ejb3.invocation](默认任务-19)   JBAS014134:对于方法,组件GastoDAOImpl上的EJB调用失败   公共抽象dominio.Gasto   persistencia.GastoDAO.getGastoporID(INT):   javax.ejb.EJBTransactionRolledbackException:找不到查询的实体

     

引起:javax.persistence.NoResultException:找不到实体   查询

     
    

15:11:16,405 ERROR [org.jboss.as.ejb3.invocation](默认任务-19)     JBAS014134:组件GastoControladorImpl上的EJB调用失败     方法公共抽象dominio.Gasto     controladores.GastoControlador.obtenerGastoporID(INT):     javax.ejb.EJBTransactionRolledbackException:找不到查询的实体

         15:11:16,439严重     [javax.enterprise.resource.webcontainer.jsf.context](默认任务-19)     javax.faces.component.UpdateModelException:javax.el.E​​LException:     /editargastos.xhtml @ 10,64 value =&#34;#{gastoBean.idGasto}&#34;:     javax.ejb.EJBTransactionRolledbackException:找不到查询的实体

  

奇怪的是,如果我在调试模式下运行程序,根本没有问题,系统只是按预期工作(数据被正确修改,用户只需返回主网格。

我的代码:

1)这是显示将要修改的项目的记录的页面  它在调试模式或正常模式下显示正确的记录

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <f:metadata>
            <f:viewParam name="id_gasto" value="#{gastoBean.idGasto}"/>
        </f:metadata>

        <title>Gaston editar un gasto</title>
    </h:head>
    <h:body>
        <div id="header">
            <ui:insert name="header">
                <ui:include src="defaultHeader.xhtml" />
            </ui:insert>  
        </div>

        <h2>Editar un gasto  Propietario: #{loginBean.usuario.apellido}</h2>
        <h3>Familia: #{loginBean.usuario.familia.nombre}</h3>

        <h:form>
            <h:messages></h:messages>
            <p:panelGrid columns="2">
                <h:outputText value=" Fecha de pago" />     
                <p:calendar value="#{gastoBean.gasto.fecha_registro}" required="true"/>
                <h:outputText value=" Moneda" />     
                <h:selectOneMenu id="moneda" value="#{gastoBean.gasto.moneda}" >
                    <f:selectItems value="#{gastoBean.monedas}"></f:selectItems>
                </h:selectOneMenu>
                <h:outputText value="Monto" />   
                <h:inputText value="#{gastoBean.gasto.monto}" required="true"/>
                <h:outputText value=" Descripcion" />     
                <h:inputText value="#{gastoBean.gasto.descripcion}" required="true"/>
                <h:outputText value=" Clasificacion" />     
                <h:inputText value="#{gastoBean.gasto.clasificacion}" required="true"/>

            </p:panelGrid>
            <br></br>

            <p:commandButton action="#{gastoBean.modificarGasto()}" value="Modificar gasto" />
            <p:commandButton action="#{gastoBean.eliminarGasto(id_gasto)}" value="Eliminar gasto" />

            <br></br>
            <h:outputText value="#{gastoBean.mensaje}"  />
            <br></br><br></br>
            <hr></hr>
            <small>Todos los campos son obligatorios</small>
        </h:form>
    </h:body>
</html>

2)Backing bean:这是上一页中修改项调用的bean,当系统在调试模式下运行时,我可以看到每一行都按预期工作,并且在完成后更新数据库并且用户是发送到网格。

但是......如果我在没有调试选项的情况下运行程序,它根本不起作用,也不会修改数据库,也不显示用户重定向和异常。

public void modificarGasto() {
    try {
        controlador.modificarGasto(gasto);
        Familia f = this.autenticado.getUsuario().getFamilia();
        this.listaGastos = controlador.obtenerGastosFamiliaporID(f.getId_familia());
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();

        ec.redirect("listadog.xhtml");
    } catch (Exception e) {
        this.mensaje = "ERROR: No se pudo guardar el registro";
    }
}

更新:我刚刚修改了附加在按钮上的方法,只是为了给出一条消息,而且在&#34;普通模式&#34;我盯着认为它在Primefaces中实际上是一个错误:(

2 个答案:

答案 0 :(得分:3)

  

javax.persistence.NoResultException:找不到查询的实体

当您使用JPA Query#getSingleResult()并且查询实际上没有返回任何结果时,将抛出此特定异常。您应该读取负责调用此方法的naildown异常的堆栈跟踪,并了解为什么此时正在调用此方法。

基于到目前为止提供的稀疏信息(实际上,完整的堆栈跟踪几乎可以解释和回答所有内容;记得在关于您无法解释的异常的任何问题中完整地发布堆栈跟踪),我可以只是做出有根据的猜测,你将<f:viewParam>绑定到请求范围的bean而不是视图范围的bean,并且它以某种方式触发一些代码,这些代码将作为请求参数提供的ID转换为使用该实体的实际实体使用getSingleResult()的JPA查询。当您在该视图中提交表单时,将重新创建请求范围bean,并且实体将为null,<f:viewParam>将再次运行,但初始请求参数不再存在。

对于视图作用域数据滥用会话范围的bean,就像在您尝试的答案中一样,是错误的解决方案。您至少需要一个视图范围的bean。而且,根据问题的真正根本原因,您可能需要进行一些更改。提示可以在下面的“另请参见”链接中找到:

另见

答案 1 :(得分:-1)

好吧,我仍然不知道为什么当我调试它工作并且在“正常模式不行”但是经过更长时间或者解决它之后我找到了另一种方法来做我想要的所以我分享信息以防万一其他可能有用。

我删除了param的代码

相反,我在网格中添加了一个方法,将项目保存在会话bean中,然后使用edit.xhtml呈现IT可以处理它。

无需进一步更改