1
votes

I'm using JSF and Primefaces. I have an edit.xhtml page with a f:viewParam receiving an entity id:

<f:viewParam name="id" value="#{backingBean.entity}" converter="entityConverter" />

I have two commandButton, one to submit and save the entity:

<p:commandButton ajax="false" value="#{bundle.save}" 
action="#{backingBean.save()}"/>

Another to add an item to a collection of the entity:

<p:commandButton ajax="true" process="@this" value="#{bundle.add}" 
actionListener="#{backingBean.addItem()}" />

This is my BackingBean:

@ViewScoped 
@Named("backingBean")
public class BackingBean {
  @EJB
  MyDAO myDAO;

  private Entity entity; //with getters and setters

  public void addItem() {
    entity.getData().add(new Item()); //another entity object
  }

  public void save(){
    myDAO.save(entity);
  }
...
}

Also I have an EntityConverter class that invoques the DAO and load the object:

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    try {
        return myDAO.findById(Entity.class, Long.valueOf(value));
    } catch (Exception e) {
        return null;
    }
}

If I try to add more than one items or if I click on save button, the Entity in the BackingBean class is reloaded by calling the getAsObject method of the converter class.

What I'm doing wrong? Thanks!

1

1 Answers

2
votes

For clarity the normal f:param will always behave that way. I use in all my projects OmniFaces ViewParam which fixes these issues.

Stateless mode to avoid unnecessary conversion, validation and model updating on postbacks

The standard UIViewParameter implementation calls the model setter again after postback. This is not always desired when being bound to a view scoped bean and can lead to performance problems when combined with an expensive converter. To solve this, this component by default stores the submitted value as a component property instead of in the model (and thus in the view state in case the binding is to a view scoped bean).

The standard UIViewParameter implementation calls the converter and validators again on postbacks. This is not always desired when you have e.g. a required="true", but the parameter is not retained on form submit. You would need to retain it on every single command link/button by . To solve this, this component doesn't call the converter and validators again on postbacks.