-1

I found a weird behavior in JSF/PrimeFaces and ask your help to understand and get around it. The actionListener method in a commandButton is executed just once.

Contextualization:

I put a link in start page of my project to a second page, renderized as follows:

http://localhost:8080/MeusTestes-war/faces/somepage.xhtml?id=1

Notice there is a parameter sent by query string.

The somepage.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>

    <f:metadata>
        <f:viewParam name="id" value="#{someBean.id}" required="true" />
        <f:viewAction action="#{someBean.init}" />
    </f:metadata>

    <h:body>
        <h:form id="form1">
            <p:commandButton id="teste1" 
                             value="Teste" 
                             actionListener="#{someBean.doTeste}" />
        </h:form>
    </h:body>
</html>

As you can see, its extremely simple. Notice there is a metadata section doing the parameter reception and the execution of init() method. In page body there is a p:commandButton and a actionListener pointing to doTeste().

There is my Bean:

@Named(value = "someBean")
@ViewScoped
public class SomeBean implements Serializable {

    private int id;

    public SomeBean() {
    }

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public void init() {
        System.out.println("init " + id);
    }

    public void doTeste(ActionEvent actionEvent) {
        System.out.println("doTeste " + id);
    }

}

Well, now the mysterious behavior:

1) When page is loaded, as expected, the init() method shows a message with the correct property value got by viewParam. 2) Firing the button, as expected too, the doTeste() method shows a message with the correct property value. However, 3) Firing the button again, nothing happens!

Other facts:

If I remove the metadata section the doTeste() method is executed as many times as the button is clicked, which is supposed to happen. But the property, obviously, is not initialized.

If I switch the button definition from p:commandButton to h:commandButton, the doTeste() method is executed as expected AND the property is initialized. But I lose the PrimeFaces pattern.

My question:

How to do the commandButton actionListener from PrimeFaces behave the way is expected? (executing the method each time it is fired)

Thanks!

Robinson RK
  • 25
  • 2
  • 8
  • possible duplicate of [f:viewParam with Converter and ViewScoped exception out when invoke the second ajax request](http://stackoverflow.com/questions/10526431/fviewparam-with-converter-and-viewscoped-exception-out-when-invoke-the-second-a) – Luiggi Mendoza Oct 05 '14 at 05:35

1 Answers1

1

If you for testing purposes add a <p:growl id="msgs"/> and add update="msgs" to the button you'll see that validation fails on subsequent requests (because of required="true" on the viewParam).

So you can either

  1. remove required="true". Probably a bad idea since you need it.
  2. add the parameter to the commandButton with <f:param name="id" value="#{someBean.id}"/>
  3. use OmniFaces <o:viewParam>.

There is a more technical explanation here.

Community
  • 1
  • 1
Jaqen H'ghar
  • 4,305
  • 2
  • 14
  • 26
  • The message shows a validation error, value required. But I didn't change the page, the view scope must not be lost, right? – Robinson RK Oct 04 '14 at 14:04
  • This behavior just happens on PrimeFaces. Is that a bug? – Robinson RK Oct 04 '14 at 14:05
  • No it should be the same bean, you can be totally sure by printing to log in the constructor, but if you're using javax.faces.view.ViewScoped it's the same. As BalusC says "the runs on every single HTTP request, also on postbacks", that's the problem. Yes I'd say it's a bug that will be fixed some day, for now you can just add the parameter to the p:commandButton. h:commandButton don't use ajax maybe that's the reason it works – Jaqen H'ghar Oct 04 '14 at 14:13
  • I found a lot of posts mentioning some like that, the most involving ajax in components. I think it's a serious issue. Not all can be easily overcome. – Robinson RK Oct 04 '14 at 14:26
  • @RobinsonRK IMO it's not an issue, and looks like you're not trying to understand how to solve the problem. BalusC is very explicit in the duplicate Q/A: pass the paramater set in `` as a parameter in your `UICommand`s (e.g. ``) or use `` from OmniFaces which is suited for your desired behavior. It's up to you to take one of these solutions or to keep ranting about how JSF works. – Luiggi Mendoza Oct 05 '14 at 05:38
  • You don't need to throw stones @luiggi-mendoza, I would not ask if I don't needed your help. It still looks like a concept bug for me. – Robinson RK Oct 06 '14 at 12:08
  • Please @jaqen-hghar, post the answer. – Robinson RK Oct 06 '14 at 12:10