0
votes

I have an "extendedDataTable" like this:

<h:form>
    <rich:extendedDataTable id="someTbl"
                            value="#{someBean.allData}"
                            var="dataItem"
                            selection="#{dataSelectionListener.selection}"
                            selectionMode="single">
        <a4j:ajax execute="@form"
                  render="@none"
                  event="selectionchange"
                  listener="#{dataSelectionListener.onSelectionChange}"/>
        <rich:column>
            <h:outputText value="#{dataItem.name}"/>
        </rich:column>
    </rich:extendedDataTable>
</h:form>

and managed bean:

@Named
@RequestScoped
public class SomeBean {
    @Inject
    private SomeService someService;

    public List<DataItem> getAllData() {
        // Getting data from DB
        return someService.getAllData();
    }
}

dataSelectionListener is also managed bean with scope "session".

Every time I select some row in my table method getAllData is called twice (first before calling of the method onSelectionChange and thereafter). It causes two unwanted queries to DB.

What is the right way to resolve this issue?

Sorry if my question is somewhat silly and thanks in advance.

2
Do you really need @RequestScoped bean? Try with @SessionScoped bean. - Vasil Lukach

2 Answers

0
votes

I think that your problem is related to @RequestScoped annotation. Request scope means that the object is defined as an attribute attached to the HttpRequest object and shares its lifetime. The HttpRequest object is created when the application container accepts an HTTP request from the client. It is effectively destroyed (goes out of scope) when the container has finished transmitting the response to that request. When a new HTTP request comes in, a new request-scope object is created. So anything that you want to exist between HTTP requests has to be placed in a longer-lived scope (such as session scope), or the data has to to be sent back as part of the response in such a way that it will be sent back as part of the next request.

0
votes

After short research (thanks to the old article in BalusC's blog) I found out that double call of the method that provides data for the table is okay in JSF world (first time getter is called during phase APPLY_REQUEST_VALUES and second - during phase RENDER_RESPONSE). So I really shouldn't use bean with scope "request". As I understood the best scope for this case is "view" in conjunction with a lazy data loading in the getter:

@ManagedBean
@ViewScoped
public class SomeBean {
    @Inject
    private SomeService someService;
    private List<DataItem> allData;

    public List<DataItem> getAllData() {
        if (allData == null)
            // Getting data from DB
            allData = someService.getAllData();
        return allData;
    }
}