(Please view edit down below)
As a continuation of the code from this SO question, I am now trying to save the modified values of a <h:dataTable>
using the persistance of the entity class.
I have a dataTable as follows:
<h:form>
<h:dataTable id="userTable" value="#{admin.customerList}"
var="c"
binding="#{admin.customerTable}"<!-- Not sure if this is necessary -->
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="All registered customers" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="User ID" />
</f:facet>
<h:outputText value="#{c.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Username"/>
</f:facet>
<h:outputText value="#{c.username}" rendered="#{not c.editable}"></h:outputText>
<h:inputText value="#{c.username}" rendered="#{c.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{c.email}" rendered="#{not c.editable}"></h:outputText>
<h:inputText value="#{c.email}" rendered="#{c.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Banned?"/>
</f:facet>
<h:selectBooleanCheckbox value="#{c.banned}" rendered="#{not c.editable}" disabled="true"></h:selectBooleanCheckbox>
<h:selectBooleanCheckbox value="#{c.banned}" rendered="#{c.editable}" disabled="false"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Admin?"/>
</f:facet>
<h:selectBooleanCheckbox value="#{c.admin}" rendered="#{not c.editable}" disabled="true"></h:selectBooleanCheckbox>
<h:selectBooleanCheckbox value="#{c.admin}" rendered="#{c.editable}" disabled="false"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{admin.editAction(c)}" rendered="#{not c.editable}" />
<h:commandButton value="Save" action="#{admin.saveAction(c)}" rendered="#{c.editable}" />
</h:column>
</h:dataTable>
</h:form>
The table is populated successfully, and when I click the edit button in the last column, I am able to modify the values of the columns. If I then click the Save
button of the last column, #{admin.saveAction(c)}
, is called with the parameter c
, which is the customer that I believe I have just modified.
The method is called, though no changes are being made.
saveAction(Customer c)
looks like this:
public String saveAction() {
for (Customer customer : customerList) {
System.out.println("Trying to update customer with ID: " + customer.getId());
customerFacade.updateCustomer(customer);
}
return null;
}
and updateCustomer(Customer c)
looks like this:
public void updateCustomer(Customer c) {
em.merge(c);
}
Either I have not understood how the variable c
corresponds to a Customer
object in the list of customers customerList
, or I have not successfully bound it to it's property. Simply put, no changes are made to the Customer
object when I modify any of the fields.
Is there a way to bind the properties of each Customer object c
in customerList
, so that the values are being updated when the fields in the datatable connected to the current object is being changed?
Must I use a listener that monitors if a field is being modified, and then calls the setter of the objects property?
Edit:
Summarize of the changes to the code that I've made.
The main issue seems to be the fact that the customer
object (entity class) doesn't get modified when I modify the field values in the datatable.
The saveAction
method now look as follows
public String saveAction() {
for (Customer customer : customerList) {
System.out.println("Trying to update customer with ID: " + customer.getId());
customerFacade.updateCustomer(customer);
}
return null;
}
The bean class:
@ManagedBean(name = "admin")
@ViewScoped
public class AdminBean implements Serializable {
@EJB
CustomerFacade customerFacade;
private List<Customer> customerList = new ArrayList<>();
@PostConstruct
public void init() {
customerList = customerFacade.findAll();
}
...
So, the main question is now only why my values aren't being updated?