简体   繁体   中英

How do I save an Object from selectOneMenu using Omnifaces Converter into a database?

I have a problem using a OmniFaces converter with primefaces selectOneMenu. I am displaying a list of Departments in a primefaces datatable with in-cell editing function, one column displays department name while the other displays faculty name. When editing, the selectOneMenu shows correctly with a list of faculties to select from but won't get saved on submitting, when i remove the faculty column in datatable, the department name get saved without a problem, someone help me find out why i cant save faculty name.

Here are is my datatable code

<p:dataTable id="deptTable" var="department"
        value="#{departmentMB.departmentList}" editable="true"
        rowIndexVar="rowIndex">

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

        <p:column headerText="Name">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{department.departmentName}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{department.departmentName}" />
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column headerText="Faculty">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{department.faculty.facultyName}" />
                </f:facet>
                <f:facet name="input">
                    <p:selectOneMenu id="iterator"
                        value="#{departmentMB.selectedFaculty}"
                        converter="facultyConverter" label="Faculty">
                        <f:selectItem itemLabel="Select one" noSelectionOption="true" />
                        <f:selectItems value="#{facultyMB.facultyList}" var="faculty"
                            itemLabel="#{faculty.facultyName}" itemValue="#{faculty}" />
                    </p:selectOneMenu>
                </f:facet>
            </p:cellEditor>
        </p:column>

        <p:column>
            <p:rowEditor />
        </p:column>

    </p:dataTable>

here is department controller

@ManagedBean(name = "departmentMB")
@RequestScoped
public class DepartmentController implements Serializable {

@ManagedProperty(value = "#{DepartmentService}")
IDepartmentService departmentService;


private static final long serialVersionUID = 1L;

private int department_id;
private String departmentName;
private Faculty selectedFaculty;
.
.
.//getters and setters

Here is onEdit method public void onEdit(RowEditEvent event) {

    try {
        Department department = (Department) event.getObject(); 
        DepartmentController departmentController = (DepartmentController) FacesContext
                .getCurrentInstance().getExternalContext().getRequestMap()
                .get("departmentMB");

        departmentController.updateDepartment(department);

    } catch (Exception e) {
        e.printStackTrace();

    }
}

Here is the update method - uses hibernate save() method

public void updateDepartment(Department department) {
    try {
        getDepartmentService().updateDepartment(department);

    } catch (DataAccessException e) {
        e.printStackTrace();
    }

}

And finally my OmniFaces Converter

@FacesConverter("facultyConverter")
public class FacultyConverter extends SelectItemsConverter {
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    Integer id = (value instanceof Faculty) ? ((Faculty) value).getFacultyId() : null;
    return (id != null) ? String.valueOf(id) : null;
}

}

In the <p:selectOneMenu> , you need to set the selected faculty on the currently iterated row, not on the parent backing bean.

In other words, replace

<p:dataTable ... value="#{departmentMB.departmentList}" var="department">
    ...
    <p:selectOneMenu ... value="#{departmentMB.selectedFaculty}">

by

<p:dataTable ... value="#{departmentMB.departmentList}" var="department">
    ...
    <p:selectOneMenu ... value="#{department.faculty}">

This concrete problem is further unrelated to the converter. It is doing its job just fine.

Wrong question. JSF is a presentation framework, it does not handle storage/bussiness logic.

In your backing bean, the appropiate method should take care of storage, but it will ignore from where your bean comes. You can do manually (JDBC) or with an ORM framework (Hibernate, JPA)

And BTW, if your question is "Why the selected object is not stored in departmentMB.selectedFaculty ?", your converter is not implementing getAsObject()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM