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());
}
}
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
).