0
votes

I write a JSF 2 page which visualizes data from database.
When I use Primefaces datatable with ViewScoped or RequestScoped bean getting values from a database it doesn't work properly - doesn't sort and doesn't paginate. For example:

@ManagedBean
@ViewScoped
public class MyBean implements Serializable {

    private List<Animal> animals;

    public List<Animal> getAnimals() {
        if(animals == null) {
            animals = DataBaseConnector.getLastAnimals();
        }
        return animals;
    }
}

When I change ViewScoped with SessionScoped it works well, but I want to use it with RequestScope and ViewScope. When I use the same bean with adding static values like here:

@ManagedBean
@ViewScoped 
public class MyBean implements Serializable {

    private List<Animal> animals = new ArrayList<Animal>() {{
        add(new Animal("John", 7, new Timestamp(2436343516841235621L)));
        add(new Animal("Holly ", 15, new Timestamp(52343332153212142L)));
        add(new Animal("Betty", 3, new Timestamp(2346236232151232L)));
    }};

    public List<Animal> getAnimals() {
        return animals;
    }
}

It works properly - it sorts and paginates. Can I use primefaces datatable with RequestScoped bean getting values from database?

3
the only difference I see between your code snippets is that in the first one you are obtaining the values from a database and at the other one you are initialising them when the class is instantiated. Nothing regarding the scope of the bean as it is the same in both samples. The way you obtain the values is indifferent from primefaces.Alonso Dominguez
I had issues like you did with getting primefaces datatable sorting and paging to work with view, can you post your html as well? there may be something causing the paging/sorting not to work. And which version of PF are you using?BestPractices

3 Answers

1
votes

That can happen if you're binding properties of a view scoped bean to attributes of a tag handler, which would cause the view scoped bean to be recreated on every single HTTP request. Tag handlers are the JSTL tags like <c:if>, <c:forEach>, etc and the Facelets UI tags which does not have rendered attribute like <ui:include>, <ui:composition>, etc and the JSF core components like <f:attribute>, <f:validator>, etc. You need to make sure that you do not bind properties of a view scoped bean to those tag handlers. You need to look for a JSF UI component approach instead, or to split those properties into a different, request scoped, bean.

See also:


Unrelated to the concrete problem, while lazy loading in a getter should absolutely not form a problem, it is preferable to do so during (post)construction of the backing bean. Although the class name DataBaseConnector and the static method call doesn't give me a strong feeling that you're doing DB stuff the right way.

0
votes

It could work, but it is better if the instruction

 animals = DataBaseConnector.getLastAnimals();

is inside a method anotated with @PostConstruct.

Still I think the best option is to use View scoped bean in your case. I have done it before and it worked well.

0
votes

Some description of the classes involved would be helpful here.

@Named
@ViewScoped
public class MyBean implements Serializable {

    private List<Animal> animals = null;

    public List<Animal> getAnimals() {
        if(animals == null) {
            animals = (new MyBean()).getLastAnimals();
        }
        return animals;
    }
}

If you update your question with the source to DatabaseConnector you will get the answer you want. Probably you need a MyBean instance inside DatabaseConnector. Composition, in that DatabaseConnector has-a MyBean.

Dollars to donuts DatabaseConnector doe not currently have a "has-a" relationship (composition) with MyBean. Or, if it does, then the DatabaseConnector.getLastAnimals() method isn't using it.