【问题标题】:Primefaces LazyDataModel with unknown quantity of items throwing IllegalArgumentExceptionPrimefaces LazyDataModel 与未知数量的项目抛出 IllegalArgumentException
【发布时间】:2015-07-02 14:15:36
【问题描述】:

我正在尝试使用 LazyDataModel 向 <p:dataScroller> 提供未知数量的项目。我根据请求(来自用户交互)从存储中读取它们,然后将所需数量发送回模型。

项目确实有尽头,但直到我都读完才知道数量,所以我在 DataModel 上设置了 1,000 个项目的上限。

Model中load()的实现:

@Override
public List<MyPojo> load(int first, int pageSize, String sortField,
        SortOrder sortOrder,
        Map<String, Object> filters) {
    return managedBean.loadMoreItens(first, pageSize);
}   

还有loadMoreItens(int, int):

List<MyPojo> loadMoreItens(int first, int pageSize) {

    int amountLoaded = 0;
    while(first+pageSize > this.list.size()) {
        if (this.endReached) {
            break;
        }
        amountLoaded++;
        list.add(readNewItem()); //readNewItem sets boolean if it reaches the end.
    }
    int end = first + pageSize;

    // do some other unrelated stuff like logging and such.

    return list.subList(first, Math.min(end, list.size()));
}

它工作正常,每次用户滚动组件时都会加载chunkSize itens(所以我将跳过在这里发布 JSF),但是当到达终点时,会抛出一个讨厌的异常:

Jul 02, 2015 10:58:51 AM com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback visit
SEVERE: java.lang.IllegalArgumentException: fromIndex(380) > toIndex(371)

这里的380 / 371数字是随机生成的测试质量,所以数量可能会发生变化。问题是要读取的项目已到末尾,但模型仍然认为少于 1,000 个。

如何避免抛出该异常?

PS:

  1. 项目并非来自数据库。如果不获取所有物品,就无法进行“轻量查询”来了解数量。
  2. 获取新物品的过程非常昂贵(无法分辨它们是什么),除非需要,否则不应这样做。
  3. managedBean 使用前 20 个项目进行初始化,这在需求规范中。可能有数百个,也可能有几十个。有 1,000 项硬性上限。
  4. 托管 bean 会在初始化lazyModel 之前尝试获取 20 个项目,因此如果项目少于 20 个,我可以设置正确的数量,但会低于 0.1% 的情况。

【问题讨论】:

  • 你应该计算之前的项目,就像一个轻计数查询,如果它是空的,至少只是第一次......
  • @HatemAlimam 这不是数据库查询——在我全部阅读之前,数量真的是未知的——而且获取这些物品的成本相当高,所以重点是只按需加载它们。我根据需求规范用前 20 个项目初始化 managedBean。
  • 组件在设计上依赖于计数,最好的办法是在某处捕获该异常......
  • @HatemAlimam 在我的代码返回后由 facesEngine 引发异常,我能想到的唯一方法是设置一个过滤器并在 chain.doFilter 上尝试捕获它()。在应用程序上设置过滤器将超出我正在设计的组件的范围。
  • 查看 github 问题。数据表有一个“解决方案”,我认为可以移植到数据滚动器。有关其他解决方法,请参阅 googlecode 中的旧问题列表。搜索“未知数”

标签: jsf-2 primefaces lazy-loading


【解决方案1】:

正如@Kukeltje 所指出的,这是一个已被 PF 项目负责人标记为 new-feature 的问题,因此在 Primefaces 发布该功能之前没有解决方案。

https://code.google.com/p/primefaces/issues/detail?id=5750

https://github.com/primefaces/primefaces/issues/51

解决方法对我不起作用,因为问题出在分页数据表上,而我正在使用 dataScroller。

问题出在 subList() 命令上;我不得不将两个索引都限制为list.size()

List<MyPojo> loadMoreItens(int first, int pageSize) {

    int amountLoaded = 0;
    while(first+pageSize > this.list.size()) {
        if (this.endReached) {
            break;
        }
        amountLoaded++;
        list.add(readNewItem()); //readNewItem sets boolean if it reaches the end.
    }
    int end = first + pageSize;

    // do some other unrelated stuff like logging and such.

    return list.subList(Math.min(first,list.size()), Math.min(end, list.size()));
}

它会跳过其余部分并避免异常,但加载控件不会从页面中消失。

然后我添加了一个 javascript 代码以在通过 remoteCommand 到达终点时将其隐藏。

【讨论】:

    猜你喜欢
    • 2012-03-08
    • 1970-01-01
    • 2014-06-15
    • 2019-03-10
    • 2017-03-31
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    相关资源
    最近更新 更多