jsfprimefacesconvertersviewparams

f:viewParam bean property recreated on submit via Converter


I have following JSF page. I pass id as a param to it and converter creates object in backing bean using that id. This is page is basically to edit existing record in database. When save is pressed my roleInformation object is recreated using converter, and thus new name and description from inputtext is not set, how can i fix it? How to prevent Converter from inserting new roleInformation when commandButton is clicked?

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:p="http://primefaces.org/ui"
            template="/WEB-INF/template.xhtml">
<ui:define name="metadata">
    <f:metadata>
        <f:viewParam name="id" value="#{roleEdit.roleInformation}"
                     converter="#{roleConverter}"
                     required="true" requiredMessage="Bad request, please use a link from within the system."
                />
        <f:viewAction action="#{roleEdit.init}"/>
    </f:metadata>
</ui:define>
<ui:define name="content">

    <h3>Here you can edit information about the single role #{param} </h3>

    <h:form>
        <p:dataTable id="roleTable" var="roleInformation" value="#{roleEdit.roleInformation}">
            <p:column headerText="Id">
                <h:outputText value="#{roleInformation.id}"/>
            </p:column>
            <p:column headerText="Name">
                <p:inputText value="#{roleInformation.name}"/>
            </p:column>
            <p:column headerText="Description">
                <p:inputText value="#{roleInformation.description}"/>
            </p:column>
        </p:dataTable>
        <br/>
        <p:pickList value="#{roleEdit.rightInformations}" var="rightInformation" itemLabel="#{rightInformation.id}"
                    itemValue="#{rightInformation}" converter="#{rightConverter}">
            <f:facet name="sourceCaption">Available</f:facet>
            <f:facet name="targetCaption">Role rights</f:facet>
            <p:column style="width:100%">
                #{rightInformation.name}
            </p:column>
        </p:pickList>
        <p:commandButton value="Save" action="#{roleEdit.save}">
        </p:commandButton>
    </h:form>
</ui:define>

UPDATE

@ManagedBean(name = "roleEdit")
@ViewScoped
public class Edit implements Serializable {

private DualListModel<RightInformation> rightInformations;
private RoleInformation roleInformation;

@Inject
@RoleServiceJPA
private RoleService roleService;

@Inject
@RightServiceJPA
private RightService rightService;

public void init() {
    List<RightInformation> target = new ArrayList<>();
    List<RightInformation> source = rightService.find(null);
    source.removeAll(roleInformation.getRightInformations());
    target.addAll(roleInformation.getRightInformations());
    rightInformations = new DualListModel<>(source, target);
    System.out.println("init roleinfor tostring " + roleInformation.toString());
}

public String save() {
    System.out.println("role save to string " + roleInformation.toString());
    System.out.println(roleInformation.getName());
    System.out.println(roleInformation.getDescription());
    roleInformation.getRightInformations().clear();
    roleInformation.getRightInformations().addAll(rightInformations.getTarget());
    roleService.updateRole(roleInformation);
    return "role?faces-redirect=true&id=" + roleInformation.getId();
}

RoleInformation Interface

public interface RoleInformation {
long getId();

String getName();

String getDescription();

List<RightInformation> getRightInformations();

void setName(String name);

void setDescription(String description);

}

RoleConverter

@ManagedBean
@FacesConverter(forClass = RoleInformation.class)
public class RoleConverter implements Converter, Serializable {

@Inject
@RoleServiceJPA
private RoleService roleService;

@Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
    if (value == null || value.isEmpty()) {
        return null;
    }

    Long id = Long.valueOf(value);
    return roleService.findSingle(id);
}

@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
    return Long.toString(((RoleInformation) o).getId());
}
}

Solution

  • The problem was that backing bean was recreated when i pressed commandButton. @ManagedBean was jsf annotation, after switching to @Named i was able to achieve what i wanted(backing bean was not recreated, thus i was able to save String from inputText).