0
votes

(Problem solved) I have a jsf2-spring-hibernate project and everytime I click a button both the constructor and postconstruct in the bean are being called and the actual click listener that I want to execute is being ignored. Note the bean is sessionscoped (not request), possibly it should be viewscoped - but would this interfere with Spring? Note2: I tried ViewScoped and same result.

The problem that clued me in was that the clickListener (below) was not executing

<h:selectOneListbox id="listBox" value="#{ScheduleMB.clients}" size="5"  
    rendered="#{ScheduleMB.showClients}" >
    <f:selectItems value="#{ScheduleMB.clientList}" var="c"
    itemLabel="#{c.lastName}" itemValue="#{c.lastName}" />
    <f:ajax event="click" listener="#{ScheduleMB.clickListener}"  
    render="group" />
</h:selectOneListbox>

What I am attempting to do is have a list of clients appear when a user clicks a button(button not shown above but included in full jsf2 page below). When the user clicks the listbox the clicklistener is activated and the bean processes the clicked value.

2nd Edit - My facelet includes binding to the bean, and this seems to be what causes the bean to be reconstructed in viewscope, but not sessionscope.

Edit - I made some changes 1) I made sure the class my bean extends was abstract. That allowed ajax code to work, however constructor still ran several times even when viewscoped, I'm not sure that should be happening. 2) Changed scope to session and everything works fine with the other changes.

So my question is, why is the constructor still firing multiple times when ViewScoped?

Original Question:

Below is the full jsf2 page (and below that the javabean).

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:t="http://myfaces.apache.org/tomahawk">


<h:form>   

    <h3>TimeOnly</h3>

    <t:div style="position: absolute; left: 5px; top: 5px; right: 5px; width: 875px ">
        <t:schedule value="#{ScheduleMB.model}" id="schedule1"
            binding="#{ScheduleMB.schedule}"
            rendered="true" visibleEndHour="18" visibleStartHour="8"
            workingEndHour="17" workingStartHour="9" readonly="false"
            theme="default" tooltip="true"
            submitOnClick="true"
            mouseListener="#{ScheduleMB.scheduleClicked}"
            action="#{ScheduleMB.scheduleAction}" />
    </t:div>

    <t:div style="position: absolute; left: 925px; top: 5px; width: 210px; overflow: auto">
        <h:panelGrid columns="1">
            <t:inputCalendar id="scheduleNavigator"
                value="#{ScheduleMB.model.selectedDate}" />
        </h:panelGrid>
    </t:div>

    <t:div style="position: absolute; left: 890px; top: 190px; width: 325px; overflow: auto; font-size: 14px; 
        text-align: left; height: 270px" >
        <h:panelGrid columns="1" rendered="true">
            <h:outputLabel>Enter From Date:Time</h:outputLabel>

            <t:inputDate popupCalendar="true" type="both" value="#{ScheduleMB.from}"/>

            <h:outputLabel>Enter To  Date:Time</h:outputLabel>

            <t:inputDate popupCalendar="true" type="both" value="#{ScheduleMB.to}"/>
            <h:outputLabel for="TitleText" value="Title:"/>
            <h:panelGroup id="group">
                <h:inputText id="TitleText" value="#{ScheduleMB.title}"/>
                <h:commandButton value="Clients" >
                    <f:ajax event="click" listener="#{ScheduleMB.clientList}"
                    render="group"/>
                </h:commandButton>

                <h:selectOneListbox id="listBox" value="#{ScheduleMB.clients}" size="5"  
                rendered="#{ScheduleMB.showClients}" >
                    <f:selectItems value="#{ScheduleMB.clientList}" var="c"
                        itemLabel="#{c.lastName}" itemValue="#{c.lastName}" />
                    <f:ajax event="click" listener="#{ScheduleMB.clickListener}"  
                        render="group" />
                </h:selectOneListbox>
            </h:panelGroup>
            <h:outputLabel for="DescText" value="Description:"/>
            <h:inputText id="DescText" value="#{ScheduleMB.description}"/>
            <h:panelGroup>
                <h:commandButton
                actionListener="#{ScheduleMB.addNewEntry}"
                value="Add entry" rendered="#{not ScheduleMB.model.entrySelected}"/>

                <h:commandButton
                actionListener="#{ScheduleMB.deleteSelectedEntry}"
                value="Delete entry"
                rendered="#{ScheduleMB.model.entrySelected}"/>
            </h:panelGroup>
        </h:panelGrid>
    </t:div>

 </h:form>
</html>

And here is the Sessionscoped bean (I've eliminated much of the irrelevant parts):

@ManagedBean(name="ScheduleMB")
@SessionScoped
public class ScheduleMB extends ScheduleBase
                                     implements Serializable
{
 Map<String,Object> clientValues = new HashMap<String,Object>();
 List<Client> clientValues2 = new ArrayList<Client>();

@ManagedProperty(value="#{UserService}")
IUserService userService;   

public ScheduleMB() {
    clients="hello";   //I put a breakpoint here just to be sure it was called

    }
@PostConstruct
public void init() {
    createClientValues();

}



//This part is not executing.
  public void clickListener(AjaxBehaviorEvent event){
    this.title = clients;
    showClients = false;
    renderClientList=false;

}



public List<Client> getClientList() {
    return clientValues2;
}

private void createClientValues() {

    clientValues2 = userService.findAllClients();

}

public void clientList() {
    showClients=true;
}


public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getClients() {
    return clients;
}

public void setClients(String clients) {
    this.clients = clients;
}

    public boolean isRenderClientList() {
    return renderClientList;
}

public void setRenderClientList(boolean renderClientList) {
    this.renderClientList = renderClientList;
}

public boolean isShowClients() {
    return showClients;
}

public void setShowClients(boolean showClients) {
    this.showClients = showClients;
}

public IUserService getUserService() {
    return userService;
}

public void setUserService(IUserService userService) {
    this.userService = userService;
}
 }
1

1 Answers

0
votes

Figured out what the problem was and how to fix it. The original symptoms were that my f:ajax click event was not firing the associated bean method and that the bean was being constructed with each interaction, despite being viewscoped. I Double checked the bean and noticed that its parent class was not abstract and had an inconsistent scope. I eliminated the scope and made it abstract. I also changed the main bean's scope to session because the facelet binds to the bean which will also cause the constructor to be called with each interaction under viewscoped. Problems solved.