1

In my JSF I have a dataTable. Each row (showing a user) has a form that takes his ID as only parameter. The problem is that the associated backing bean never gets called (neither the methods follow/unfollow nor the constructor and the PostConstruct annotated method).

searchUserResult.xhtml

<h:dataTable value="#{searchUserMB.searchResult}" var="user"
            rowClasses="tdUser"
            rendered="#{not empty searchUserMB.searchResult}">
            <h:column>
                <f:facet name="header">
                    <h:outputText value="#{bundle.Username}" />
                </f:facet>
                <h:outputText value="#{user.username}" />
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputText value="#{bundle.Name}" />
                </f:facet>
                <h:outputText value="#{user.name}" />
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputText value="#{bundle.Surname}" />
                </f:facet>
                <h:outputText value="#{user.surname}" />
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputText value="#{bundle.Action}" />
                </f:facet>
                <h:form rendered="#{userMB.user.isFollower(user.id)}">
                    <h:commandButton value="#{bundle.Unfollow}"
                        action="#{followMB.unfollow}">
                        <f:param name="followerId" value="#{user.id}" />
                    </h:commandButton>
                </h:form>
                <h:form rendered="#{not userMB.user.isFollower(user.id)}">
                    <h:commandButton value="#{bundle.Follow}"
                        action="#{followMB.follow}">
                        <f:param name="followerId" value="#{user.id}" />
                    </h:commandButton>
                </h:form>
            </h:column>
        </h:dataTable>

FollowMB

@ManagedBean
@RequestScoped

public class FollowMB {

@EJB
private DBObjectRemote db;

@ManagedProperty(value="#{userMB}")
private UserMB userMB;

@ManagedProperty(value="#{param.followerId}")
private int followerId;

public FollowMB() {
    System.out.println("I'm in the constructor");
}

@PostConstruct
public void init() {
    System.out.println("I'm in the PostConstruct");
}

public String follow() {
    // DB stuff
}

public String unfollow() {
    // DB stuff
}

public UserMB getUserMB() {
    return userMB;
}

public void setUserMB(UserMB userMB) {
    this.userMB = userMB;
}

public int getFollowerId() {
    return followerId;
}

public void setFollowerId(int followerId) {
    this.followerId = followerId;
}
}

Generated HTML:

<form id="j_idt15:0:j_idt30" name="j_idt15:0:j_idt30" method="post" 
action="/myApp/private/searchUserResult.xhtml" 
enctype="application/x-www-form-urlencoded">

<input type="hidden" name="j_idt15:0:j_idt30" value="j_idt15:0:j_idt30">

<script type="text/javascript" 
src="/myApp/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>

<input type="submit" name="j_idt15:0:j_idt30:j_idt31" value="Follow" 
onclick="mojarra.jsfcljs(document.getElementById('j_idt15:0:j_idt30'),
{'j_idt15:0:j_idt30:j_idt31':'j_idt15:0:j_idt30:j_idt31','followerId':'502'},'');
return false">

<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" 
value="-6780758405072567889:8862631453580026176" autocomplete="off">

main.jsf

<h:form>
    <h:inputText value="#{searchUserMB.searchTerm}" required="true"/><br/>
    <h:commandButton action="#{searchUserMB.search}" />
</h:form>

SearchUserMB

@ManagedBean
@RequestScoped
public class SearchUserMB {

@EJB
private DBObjectRemote db;

private String searchTerm;
private List<User> searchResult;

public SearchUserMB() {}

public String search() {
    searchResult = db.searchUser(searchTerm);

    return "searchUserResult";
}

public String getSearchTerm() {
    return searchTerm;
}

public void setSearchTerm(String searchTerm) {
    this.searchTerm = searchTerm;
}

public List<User> getSearchResult() {
    return searchResult;
}

public void setSearchResult(List<User> searchResult) {
    this.searchResult = searchResult;
}

}

user3673449
  • 347
  • 2
  • 5
  • 20
  • In your webbrowser, do rightclick and *View Source*. What exactly do you see there? Do you see the original JSF source code or its generated HTML output? – BalusC May 15 '16 at 19:07
  • OK, `FacesServlet` is properly invoked. Next step, what package did you import `@ManagedBean` annotation from? – BalusC May 16 '16 at 10:01
  • It's javax.faces.bean.ManagedBean. – user3673449 May 16 '16 at 10:03
  • OK, that's the right one. Next step, what `version` is declared and used in `faces-config.xml` root element? – BalusC May 16 '16 at 10:04
  • 2.0. (Thanks for your help!) – user3673449 May 16 '16 at 10:05
  • Sorry, let's take a step back. I now see that you're talking about `#{followMB}` and not about `#{searchUserMB}`. Is the `#{searchUserMB}` request or view scoped? It must be view scoped in order to preserve the `` and `` conditions. See also points 4 and 5 of http://stackoverflow.com/q/2118656 – BalusC May 16 '16 at 10:07
  • I updated the question. SearchUserMB is RequestScoped. I took a look at that question before and tried to set it as ViewScoped, but the result is that view receives an empty list (though the method search() returns a populated list). I guess I'm missing something in the scopes' lyfecicles. – user3673449 May 16 '16 at 10:24
  • That will indeed happen when you navigate to a different view. I suggest to render results in the same view, or to make the the search idempotent. See also a.o. http://stackoverflow.com/q/15521451 – BalusC May 16 '16 at 10:37

0 Answers0