数据表格PrimeFaces中的行编辑无法正常工作。

4

在编辑数据表的值时,这些值在屏幕上以及监听器方法中都没有更新。监听器方法:

public void onEdit(RowEditEvent event) throws ClassNotFoundException, SQLException
{
    Employee e=(Employee) event.getObject();
    name=e.getName();
    department=e.getDepartment();
    salary=e.getSalary();
    place=e.getPlace();
          ......
           ..... update query
}

我只得到了所选对象及其值,但没有更新后的值。

这是我的数据表 XHTML:

<h:form id="form">
    <p:growl id="messages" showDetail="true" />

    <p:dataTable var="e" value="#{employees.eList}" id="elist1"
        editable="true">
        <f:facet name="header">
        In-Cell Editing
    </f:facet>

        <p:ajax event="rowEdit" listener="#{employees.onEdit}"
            update=":form:messages" />
        <p:ajax event="rowEditCancel" listener="#{employees.onCancel}"
            update=":form:messages" />

        <p:column headerText="name" style="width:30%">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{e.name}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{e.name}" style="width:100%" />
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="department" style="width:20%">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{e.department}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{e.department}" style="width:100%"
                        label="department" />
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="salary" style="width:20%">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{e.salary}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{e.salary}" style="width:100%" label="salary" />
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="place" style="width:20%">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{e.place}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{e.place}" style="width:100%" label="place" />
                </f:facet>
            </p:cellEditor>
        </p:column>



        <p:column style="width:6%">
            <p:rowEditor />
        </p:column>

    </p:dataTable>

</h:form>

这是我的托管bean:

@ManagedBean(name = "employees")
@ViewScoped
public class UserData  
{
    // properties
    private String name;
    private String department;
    private String salary;
    private String place;
    private ArrayList<Employee> eList;
    private Employee selectedemp;



    private void clear()
    {
        name="";
        department="";
        salary="";
        place="";
    }

//returning all employees   
    public ArrayList<Employee> geteList() throws ClassNotFoundException, SQLException {
        Connection conn=DbConnection.connectFunc();
        Statement stmt=conn.createStatement();
        String sql="select * from employee";
        ResultSet rs=stmt.executeQuery(sql);
        eList=new ArrayList<Employee>();
        while(rs.next())
        {
            Employee emp=new Employee();
            emp.setName(rs.getString(2));
            emp.setDepartment(rs.getString(3));
            emp.setSalary(rs.getString(4));
            emp.setPlace(rs.getString(5));
            eList.add(emp);
        }
        return eList;
    }
public void onEdit(RowEditEvent event) throws ClassNotFoundException, SQLException
    {

    Employee e=(Employee) event.getObject();
     name=e.getName();
        System.out.println(name);
        department=e.getDepartment();
        System.out.println(department);
        salary=e.getSalary();
        System.out.println(salary);
        place=e.getPlace();
        System.out.println(place);

        Connection conn=DbConnection.connectFunc();
        Statement stmt=conn.createStatement();
        String sql="update employee set department='"+department+"',salary='"+salary+"',place='"+place+"'where name='"+name+"'";
        int i=stmt.executeUpdate(sql);
        if(i!=0)
        {
            FacesContext context=FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage("updated  successfully"));
        }
        conn.close();
    }
//onCancel
    public void onCancel(RowEditEvent event)
    {

    }
...setter and getters

如果我使用视图作用域,将会出现以下异常:
HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.io.NotSerializableException: com.solv.datatable.UserData
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeArray(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    com.sun.faces.renderkit.ClientSideStateHelper.doWriteState(ClientSideStateHelper.java:325)
    com.sun.faces.renderkit.ClientSideStateHelper.writeState(ClientSideStateHelper.java:173)
    com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
    com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)
    com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:419)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.26 logs.

你使用了什么作用域?也许你可以给一些datatable的代码? - Darka
@Darka 你好,我添加了数据表代码。 - vijaya kumar
4个回答

6

您的bean必须实现Serializable接口,这就是错误信息所说的。

另一个问题是您总是通过getEList返回新的List。您可以在某种类型的init方法中加载您的ArayList,该方法将具有注释@PostConstruct

@PostConstruct
public void init() {
       //code from getElist()...
}

而你的getter应该是经典的getter,只返回eList。这样,在创建视图时就加载列表。在你的情况下,每次更新都会重新加载列表,这是不好的做法。不要在getter中获取数据。你的编辑功能不能正常工作,因为每次都返回一个新的列表,导致更新的值丢失。


异常已经被修复... 但我没有得到更新后的值,仍然得到旧值。 - vijaya kumar
好的,再说一遍:执行是否进入了onEdit方法?你有检查过吗? - miroslav_mijajlovic
是的,它进入了 onEdit 方法,我的意思是 event.getObject() 方法返回旧对象而不是更新后的对象。 - vijaya kumar
我已更新我的回答。起初我没有注意到问题出在你的 geteList() 上。 - miroslav_mijajlovic
由于您是新来的,请不要忘记标记最有帮助的答案,以解决问题。 - miroslav_mijajlovic
我需要15个声望来投赞成票,但我只有8个。 - vijaya kumar

1

在你的

<p:ajax event="rowEdit" listener="#{employees.onEdit}"
            update=":form:messages" />

你只更新消息而不是数据表本身。尝试这样做:update=":form:messages, :form:elist1"。 这对我有效。

1
我将代码更改为<p:ajax event="rowEdit" listener="#{employees.onEdit}" update=":form:messages,:form:elist1" /><p:ajax event="rowEditCancel" listener="#{employees.onCancel}" update=":form:messages,:form:elist1" /> 但没有变化。 - vijaya kumar
你使用了什么作用域?是视图作用域的bean吗?你进行过调试吗?你进入了这个方法吗? - miroslav_mijajlovic
你为什么使用请求范围而不是视图范围?你有具体的原因吗?我建议的这个更新在请求范围内没有意义。 - miroslav_mijajlovic
我将作用域更改为视图,但仍然出现异常。我将异常和我的托管bean粘贴在我的问题中。 - vijaya kumar
你得到了什么异常?并且你是否在调试模式下检查过执行是否进入onEdit方法? - miroslav_mijajlovic
显示剩余2条评论

0

这可能会对某些人有所帮助。我曾经遇到过类似的问题,尝试了互联网上所有可能的方法,但最终放弃了,但后来意外地修复了它。问题在于我的.xhtml中使用了多个< h:form>,但由于某种原因更改没有传播。希望能帮到某些人。


0

我认为你需要:

  • 在 p:dataTable 标签上定义 rowKey 属性。
  • 或者实现一个数据模型(将其馈入 datatable),该数据模型实现 SelectableDataModel 接口。

rowKey 属性选项需要的工作量最少。例如: <p:dataTable var="e" value="#{employees.eList}" id="elist1" rowKey="#{e.name}" editable="true">

其中 e.name 是数据表中每个项目的标识符。它还应该是该对象的唯一值。(如 id)


我不明白为什么他(或任何其他人)不应该使用视图作用域的Bean? - miroslav_mijajlovic
没错,想一想之后,viewscoped 应该就可以了(我已从我的答案中删除了它)。 - Beele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接