I have a data table that lists Parent
items. One of the columns nests another table to list the Children
. Also in this column next to the nested children datatable I have Primeface commandButton to insert a child on that item. I also have another another column with another Primeface commandButton on each row to toggle a confirmed boolean on the parent.
If I first do an add child operation, the table gets ajaxically refreshed and I see the new child record. If I then press the other button which updates the confirmed boolean on the same parent item that I just added the child record to, the table ajaxically refreshes fine, the boolean flag gets updated correctly and I still see the added child. But in reality, the second jpa update added the child record again. I don't see the duplicate child record in the table until a do a refresh on my browser.
Here is some code
public class Parent implements Serializable {
private boolean confirmed;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = CascadeType.ALL)
@OrderBy("date")
private Set<Child> children;
public class Child implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
public class Bean
public void applyAddChild() {
newChild.setDate(new Date());
newChild.setParent(selectedParent);
selectedParent.getChildren().add(newChild);
try {
service.update(selectedParent);
Messages.addFlashMessage("Insert Successful");
} catch (Exception e) {
Messages.addFlashErrorMessage(e.getMessage());
}
newChild = new Child();
}
public void confirmSelected() {
selectedParent.setConfirmed(true);
try {
service.update(selectedParent);
Messages.addFlashMessage("Confirmed For Parent");
} catch (Exception e) {
Messages.addFlashErrorMessage(e.getMessage());
}
}
When I put a breakpoint and debug the confirmedSelected method, the children are listed as a PersistentSets
Here is the confirmed Button
<p:commandButton action="#{bean.confirmSelected()}"
rendered="#{not parent.confirmed}" value="Confirm?" update="@form">
<f:setPropertyActionListener value="#{parent}"
target="#{bean.selectedParent}" />
</p:commandButton>
And the add Child Button
<p:commandButton oncomplete="PF('addChildDialogWv').show()"
update="@form" value="Add Child">
<f:setPropertyActionListener value="#{parent}"
target="#{bean.selectedParent}" />
</p:commandButton>
If I hit refresh on the browser in between all the ajax refreshes things work just fine. I suppose I can not use ajax and do full redirect/refresh but I'd like to know why it's not working with Ajax.
EDIT
I was able to resolve my issue but I'm not sure if this is a Band-Aid or proper way. I'm explicitly swapping out the updated object in the datatable list.
New code --->
public class Bean
public void applyAddChild() {
newChild.setDate(new Date());
newChild.setParent(selectedParent);
selectedParent.getChildren().add(newChild);
---> Parent updatedParent = new Parent();
try {
---> updatedParent = service.update(selectedParent);
Messages.addFlashMessage("Insert Successful");
} catch (Exception e) {
Messages.addFlashErrorMessage(e.getMessage());
}
---> int index = parents.indexOf(selectedParent);
---> parents.set(index, updatedParent);
newChild = new Child();
}