Grails 分页结果不一致

发布于 2024-07-14 11:03:17 字数 2542 浏览 9 评论 0原文

我正在 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)

I'm doing some paging in my Grails application. Since I'm doing some special sorting, I can't use the convient sort/paging methods. Here is my paging code on the server side:

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()

You'll notice the section of code commented-out. Typically, it would be uncommented so I can do my special sorting, but it's commented-out to help reduce the number of variables causing this problem.

When I look at the 4th page of my results, I see a certain list of people. When I reload the 4th page of results, I see a slightly different list -shifted by 8 people.

Does anyone have any idea why I would be receiving inconsistent results? I would expect to get the same 100 people every time I view the 4th page of my results (If you haven't guess, I'm showing people's names). The 'offset,' 'max,' and 'sort' values are identical across both requests.

Any help is appreciated. Thanks,

Andrew

Update....

Here is the more straightforward approach that should work, except I receive an exception. If I remove the 'createAlias' line, I don't receive the exception. Unfortunately, I need the alias to join to an associated table.

            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%"
                            }
                    }
            }

Exception:

Caused by:
java.lang.IllegalArgumentException:
call to [list] not supported here

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

at
ClientContactController$_closure21_closure39_closure44.doCall(ClientContactController:494)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若相惜即相离 2024-07-21 11:03:17

我不知道为什么不同请求之间的排序不一致,但我想向您展示代码的“默认”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”属性来缓解分页。

I don't have an idea why the sorting is inconsistent across different request, but I'd like to show you the "default" grails approach for your code:

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%"
        }
    }
}

the results variable is then an instance of PagedResultList, which is basically a normal list, but has a "totalCount" property to ease the paging.

情徒 2024-07-21 11:03:17

我和你有同样的问题。 当您调用 .list() 时,您会在 HibernateCriteriaBuilder 上抛出此错误:

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

问题是您在已经存在的实例中调用 .list已设置标准。 解决方案是使用 @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 闭包内。 在此之前你不能拥有任何东西。

I'm having the same problem as you. When you call .list() you gonna throw this error on HibernateCriteriaBuilder:

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

The problem is that you are calling .list in an instance that already has criteria set. The solution would be to use something like @siegfried-puchbauer suggested, with some differences:

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%"
        }
    }
}

The difference on the other approach is that even the createAlias method must be inside the list closure. You can't have anything before this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文