1
votes

I am using a primefaces datatable and a roweditor to update the database.

When i click the roweditor it makes the column editable as expected and i change the values.

When i click the accept button on the roweditor i get the object from the event and cast it to the entity and pass that object to my model class which updates the database.

From debugging i found that when i get the Project object from the event in the onRowEdit method in the CView Bean the values i changed in the rowedit mode on the datatable was set in the Project entity, but the Project object i get from the event is the object before any changes was applied.

In other words when i edited the datatable row and changed values, the Project entity updates with the changed values, but the project object i get from the event does not have the changes i made on the datatable.

i have no idea what i am missing or not understanding, please help?

Below is more information on the setup and code

I am using Primefaces 5.1 Tomcat 7.0.53 Java EE 7

My Datatable:

        <p:dataTable var="customer" 
                     id="customerdatatable" 
                     style="font-size: 12px;" 
                     value="#{cView.list}"
                     editable="#{cView.modify}"
                     rowKey="#{customer.hashCode}"
                     emptyMessage="No Customers found."
                     widgetVar="custdtwv"
                     scrollable="true"
                     scrollHeight="7%">
            <p:ajax event="rowEdit" 
                    listener="#{cView.onRowEdit}"/>

            <p:column headerText="Customer" 
                      filterBy="#{customer.project}"
                      filterMatchMode="contains">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{customer.project}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{customer.project}" 
                                     style="width:96%;"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column headerText="Project Code" 
                      filterBy="#{customer.projectCode}"
                      filterMatchMode="contains">
                <h:outputText value="#{customer.projectCode}"/>
            </p:column>

            <p:column headerText="Contact">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{customer.contact}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{customer.contact}" 
                                     style="width:96%;"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column headerText="Phone">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{customer.phone}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{customer.phone}" 
                                     style="width:96%;"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column headerText="Email">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{customer.email1}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{customer.email1}" 
                                     style="width:96%;"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>


            <p:column headerText="Address">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{customer.address}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{customer.address}" 
                                     style="width:96%;"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column headerText="Action"
                      style="width:32px">
                <p:rowEditor />
            </p:column>
        </p:dataTable>

My bean:

@ManagedBean
@ViewScoped
public class CView implements Serializable {

private List<Project> list;

private List<Project> selected = new ArrayList<>();

private List<Project> filtered;

private Model model;

private boolean modify;

@PostConstruct
public void init() {
    model = new Model();

    modify = User.getPermissions().checkPermission(Permissions.CUSTMANAGE);
}

public List<Project> getList() {
    list = model.getList();

    return list;
}

public void setList(List<Project> list) {
    this.list = list;
}

public List<Project> getSelected() {
    return selected;
}

public List<Project> getFiltered() {
    return filtered;
}

public void setSelected(List<Project> selected) {
    this.selected = selected;
}

public void setFiltered(List<Project> filtered) {
    this.filtered = filtered;
}

public Model getModel() {
    return model;
}

public void setModel(Model model) {
    this.model = model;
}

private void update(Project upd) {
    boolean updated = model.updateProject(upd);

    if (updated) {
        Logger.getLogger(this.getClass().getName()).log(Level.INFO,
                "Project [{0}] was updated by {1}: {2}",
                new Object[]{upd.getProjectCode(), User.getFullName(), upd.toString()});

        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO,
                        "CUSTOMER [" + upd.getProjectCode() + "]", "Update successfull."));
    } else {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                "Project [{0}] could not be updated by {1}: {2}",
                new Object[]{upd.getProjectCode(), User.getFullName(), upd.toString()});

        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "CUSTOMER [" + upd.getProjectCode() + "]", "Could not be updated."));
    }
}

public void onRowEdit(RowEditEvent event) {
    Project updProject = (Project) event.getObject();

    update(updProject);
}

public boolean getModify() {
    return modify;
}

public void setModify(boolean modify) {
    this.modify = modify;
}
}

My Entity:

@Entity
@Table(name = "S_PROJECT")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Project.findAll", query = "SELECT p FROM Project p"),
@NamedQuery(name = "Project.findById", query = "SELECT p FROM Project p WHERE p.id = :id"),
@NamedQuery(name = "Project.findByProject", query = "SELECT p FROM Project p WHERE p.project = :project"),
@NamedQuery(name = "Project.findByType", query = "SELECT p FROM Project p WHERE p.type = :type"),
@NamedQuery(name = "Project.findByProjectCode", query = "SELECT p FROM Project p WHERE p.projectCode = :projectCode"),
@NamedQuery(name = "Project.findByGeo", query = "SELECT p FROM Project p WHERE p.geo = :geo"),
@NamedQuery(name = "Project.findBySelection", query = "SELECT p FROM Project p WHERE p.selection = :selection"),
@NamedQuery(name = "Project.findByLegalName", query = "SELECT p FROM Project p WHERE p.legalName = :legalName"),
@NamedQuery(name = "Project.findByContact", query = "SELECT p FROM Project p WHERE p.contact = :contact"),
@NamedQuery(name = "Project.findByPhone", query = "SELECT p FROM Project p WHERE p.phone = :phone"),
@NamedQuery(name = "Project.findByAddress", query = "SELECT p FROM Project p WHERE p.address = :address"),
@NamedQuery(name = "Project.findByDeliver", query = "SELECT p FROM Project p WHERE p.deliver = :deliver"),
@NamedQuery(name = "Project.findByEmail1", query = "SELECT p FROM Project p WHERE p.email1 = :email1"),
@NamedQuery(name = "Project.findByEmail2", query = "SELECT p FROM Project p WHERE p.email2 = :email2"),
@NamedQuery(name = "Project.updateCustomer", query = "UPDATE Project p SET p.project = :project, p.contact = :contact, p.phone = :phone, p.email1 = :email1, p.address = :address WHERE p.projectCode = :projectCode")})
public class Project implements Serializable {

private static final long serialVersionUID = 123456L;
@Basic(optional = false)
@Column(name = "ID")
private int id;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "Project")
private String project;
@Size(max = 255)
@Column(name = "Type")
private String type;
@Size(max = 255)
@Column(name = "ProjectCode")
private String projectCode;
@Column(name = "Geo")
private Boolean geo;
@Size(max = 255)
@Column(name = "Selection")
private String selection;
@Size(max = 255)
@Column(name = "LegalName")
private String legalName;
@Size(max = 255)
@Column(name = "Contact")
private String contact;
// @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
@Size(max = 255)
@Column(name = "Phone")
private String phone;
@Size(max = 255)
@Column(name = "Address")
private String address;
@Size(max = 255)
@Column(name = "Deliver")
private String deliver;
@Size(max = 255)
@Column(name = "Email1")
private String email1;
@Size(max = 255)
@Column(name = "Email2")
private String email2;

public Project() {
}

public Project(String project) {
    this.project = project;
}

public Project(String project, int id) {
    this.project = project;
    this.id = id;
}
//Getters and Setters

@Override
public int hashCode() {
    int hash = 0;

    hash += (project != null ? project.hashCode() : 0);

    return hash;
}

@Override
public boolean equals(Object object) {
    if (!(object instanceof Project)) {
        return false;
    }

    Project other = (Project) object;

    if ((this.project == null && other.project != null) || (this.project != null && !this.project.equals(other.project))) {
        return false;
    }

    return true;
}

@Override
public String toString() {
    return "za.co.xon.intranet.customer.Project[id=" + id
            + "] projectcode=[" + projectCode + "] contact=[" + contact
            + "] phone=[" + phone + "] email1=[" + email1 + "] address=[" + address + "]";
}
}
2
Does the form component change to reflect the update? You should ajax-refresh the tablekolossus
@kolossus, thanks for your reply, i found the issue and it is kind of annoying but in my getList() method in my bean i recreate the list each time the table is refreshed, as soon i moved the creation of the list to the init() method the update worked fine.Twakkie

2 Answers

2
votes

I found the issue and it is kind of annoying but my getList() method in my bean recreates the list each time the list needs to be called, as soon i moved the creation of the list to the init() method the update worked fine.

0
votes

Try with process="customerdatatable" in the <p:ajax> tag to force values to be updated:

<p:ajax event="rowEdit" 
        listener="#{cView.onRowEdit}"
        process="customerdatatable"/>