Primefaces lazy datascroller calling load twice

2019-07-21 16:30发布

I'm trying to use a Datascroller with a LazyDataModel and the load method from lazy data model is getting called twice.

Appart from thinking that it is not so good to call the load method multiple times (that may perform costly server/DB roundtrips), since my lazy data model not idempotent (meaning, two consecutive calls to the model on the same window/page size returns different outcomes) the fact that it's being called twice means: the presented results are not correct.

Is it normal for the load method in datascroller to be called twice? If so, any workarounds suggested for my alternative to work correctly? (appart from changing from statefull to stateless data model)

Using Primefaces 5.1, JSF2, Glassfish 4.1

2条回答
干净又极端
2楼-- · 2019-07-21 16:46

Since the header facet, in BalusC post, is not correctly rendered if the first load (commented section) does not run, a slightly different implementation is needed

public class DataScrollerRenderer2 extends DataScrollerRenderer {

    @Override
    protected void encodeMarkup(FacesContext context, DataScroller ds, int chunkSize) throws IOException {
        // ... 
        boolean alreadyLoaded = false;
        if (ds.isLazy()) {            
            alreadyLoaded = true;
            loadLazyData(ds, 0, chunkSize);
        }
        // ... 
        loadChunk(context, ds, 0, chunkSize, alreadyLoaded);
        // ... 
    }

    @Override
    protected void loadChunk(FacesContext context, DataScroller ds, int start, int size) throws IOException {
        loadChunk(context, ds, start, size, false);
    }

    private void loadChunk(FacesContext context, DataScroller ds, int start, int size, boolean alreadyLoaded) throws IOException {
        // ... 
        if (ds.isLazy() && !alreadyLoaded) {
            loadLazyData(ds, start, size);
        }
        // ... 
    }

}

Not sure if this is the best implementation, but it worked.

EDIT: an issue has been filed in PrimeFaces GitHub

查看更多
做个烂人
3楼-- · 2019-07-21 16:50

No, this is not normal. This is indeed a bug in PrimeFaces. We also discovered it a while ago when using it at zeef.com. We bypassed it by creating a custom renderer extending DataScrollerRenderer and overriding only encodeMarkup() method with the original implementation copypasted and then only the following piece outcommented:

// BUGFIX: outcommented as this is already done in loadChunk() later on.
/*if(ds.isLazy()) {
    loadLazyData(ds, 0, chunkSize);
}*/

You can get it to run by registering it as below in webapp's faces-config.xml:

<render-kit>    
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.DataScrollerRenderer</renderer-type>
        <renderer-class>com.example.YourDataScrollerRenderer</renderer-class>
    </renderer>
</render-kit>
查看更多
登录 后发表回答