Grails 分页结果不一致

问题描述 投票:0回答:2

我正在 Grails 应用程序中执行一些分页操作。 由于我正在进行一些特殊的排序,因此我无法使用方便的排序/分页方法。 这是我在服务器端的分页代码:

def criteria = ClientContact.createCriteria().createAlias("client", "c")
criteria.setFirstResult(params.offset?.toInteger())
criteria.setMaxResults(params.max?.toInteger())
def sortField = params.sort
if(params.sort == "clientName") sortField = "c.name"
criteria.addOrder(params.order == "asc" ? Order.asc(sortField) : Order.desc(sortField))
            /*
            if(!StringUtils.isBlank(params.searchField))
            {
                criteria.add(
                    Restrictions.or (
                        Restrictions.ilike("c.name", "%" + params.searchField + "%"),
                        Restrictions.or(
                            Restrictions.ilike("firstName", "%" + params.searchField + "%"),
                            Restrictions.ilike("lastName", "%" + params.searchField + "%")
                        )
                    )
                )
            }
                */

def results = criteria.list()

您会注意到注释掉的代码部分。 通常,它会被取消注释,以便我可以进行特殊排序,但它被注释掉以帮助减少导致此问题的变量数量。

当我查看结果的第四页时,我看到了特定的人员列表。 当我重新加载第 4 页结果时,我看到一个略有不同的列表 - 移动了 8 个人。

有人知道为什么我会收到不一致的结果吗? 我希望每次查看结果的第 4 页时都会看到相同的 100 个人(如果您没有猜到,我正在显示人们的名字)。 两个请求中的“offset”、“max”和“sort”值是相同的。

如有任何帮助,我们将不胜感激。 谢谢,

安德鲁

更新....

这是更直接的方法,应该可行,除非我收到异常。 如果我删除“createAlias”行,我不会收到异常。 不幸的是,我需要别名来加入关联的表。

            if(params.sort == 'client') params.sort = 'c.name'
            def criteria = ClientContact.createCriteria()
            criteria.createAlias('client', 'c')
            def pagedResults = criteria.list(offset: params.offset, max: params.max, sort: params.sort, order: params.order ?: 'asc' ) {
                    if(!StringUtils.isBlank(params.searchField)) {
                            or {
                                            ilike "c.name", "%$params.searchField%"
                                            ilike "firstName", "%$params.searchField%"
                                            ilike "lastName", "%$params.searchField%"
                            }
                    }
            }

例外:

原因: java.lang.IllegalArgumentException: 这里不支持调用[list]

在 grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:847)

在 ClientContactController$_closure21_closure39_closure44.doCall(ClientContactController:494)

hibernate grails pagination grails-orm
2个回答
0
投票

我不知道为什么不同请求之间的排序不一致,但我想向您展示代码的“默认”grails 方法:

if(params.sort == 'clientName') params.sort = 'c.name'
def criteria = ClientContact.createCriteria()
criteria.createAlias('client', 'c')
def results = criteria.list( sort: params.sort, order: params.order ?: 'asc' ) {
    if(!StringUtils.isBlank(params.searchField)) {
        or {
            ilike "c.name", "%$params.searchField%"
            ilike "firstName", "%$params.searchField%"
            ilike "lastName", "%$params.searchField%"
        }
    }
}

结果变量是 PagedResultList 的实例,它基本上是一个普通列表,但有一个“totalCount”属性来简化分页。


0
投票

我也遇到和你一样的问题。当你调用

.list()
时,你会在
HibernateCriteriaBuilder
上抛出这个错误:

if (this.criteria != null) {
    this.throwRuntimeException(new IllegalArgumentException("call to [" + name + "] not supported here"));
}

问题是您在已设置

.list
的实例中调用
criteria
。解决方案是使用 @siegfried-puchbauer 建议的类似方法,但有一些差异:

ClientContact.createCriteria().list(sortingParamsAsMap) {
    // You need to put ALL your criteria inside this closure
    createAlias("client", "c")

    if(!StringUtils.isBlank(params.searchField)) {
        or {
            ilike "c.name", "%$params.searchField%"
            ilike "firstName", "%$params.searchField%"
            ilike "lastName", "%$params.searchField%"
        }
    }
}

与另一种方法的区别在于,即使是

createAlias
方法也必须位于
list
闭包内。在此之前你什么都不能拥有。

© www.soinside.com 2019 - 2024. All rights reserved.