Svetoslav Marinov
Svetoslav Marinov

Reputation: 492

Primefaces datatable doesn't work properly with ViewScoped or RequestScoped bean

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?

Upvotes: 0

Views: 5176

Answers (3)

Thufir
Thufir

Reputation: 8487

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.

Upvotes: 0

BalusC
BalusC

Reputation: 1108722

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.

Upvotes: 1

Oscar Castiblanco
Oscar Castiblanco

Reputation: 1646

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.

Upvotes: 0

Related Questions