【问题标题】:Paginate sub-resources in Spring Data Rest 2.1在 Spring Data Rest 2.1 中对子资源进行分页
【发布时间】:2014-09-06 16:11:21
【问题描述】:

我使用默认配置的 Spring Data Rest 2.1.1 Release。考虑以下资源:

GET /communities/MyCommunity

{
    "creationDate": "2014-07-16T06:22:37.153+0000",
    "name": "GroupeSEB",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/communities/GroupeSEB"
        },
        "posts": {
            "href": "http://localhost:8080/api/communities/GroupeSEB/posts"
        }
    }
}

当我得到“帖子”子资源时:

GET /communities/MyCommunity/posts

{
    "_embedded": {
        "posts": [
            {
                "creationDate": "2014-07-09T13:09:14.535+0000",
                "id": "53bd3efae4b012818368c549",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/api/posts/53bd3efae4b012818368c549"
                    } 
                }
            }
        ]
    }
}

没有启用分页。由于我的父资源可以聚合大量帖子(其子资源),我如何为每个子资源启用分页?

【问题讨论】:

    标签: spring pagination spring-data-rest


    【解决方案1】:

    答案很简单:你不能。理由如下:

    关联资源表示一个主要实体与一个或多个其他实体之间的关联。因此,为了呈现这些资源,我们查找主要实体并仅访问属性。这意味着,没有存储库的使用,也没有地方分页可以应用,因为整个机制与存储无关。我们在实体实例上操作关联加载的机制是高度特定于存储的。

    因此,如果您的域模型中已经有对象关联,那么您完全受制于商店处理关联的方式。因此,即使您应用了分页,您也必须首先读取所有相关对象才能获取它们的 id。

    作为一种解决方法,您可以只使用 id 并在该路径上手动公开资源,该路径将使用 id 和关联实体存储库上的专用查询方法。

    【讨论】:

    • 面临同样的问题,在我的情况下,由于子资源由于结果集大而导致 GC 错误,情况更加严重。我想我也应该 RestExpose 假这样的资源,并在 Repository 中手动提供一个 Pageable 资源,通过 ResourceProcessor 绑定。相关链接 - stackoverflow.com/questions/26451920/…
    【解决方案2】:

    奥利弗给出的答案并不完全正确。

    在 EAGER 嵌套实体(集合)上,没有使用存储库。但是在 LAZY 嵌套实体(集合)上有 IS 存储库使用。 @One2Many 默认是 LAZY。因此,当检索父实体时,不会填充嵌套实体,也不会从 repo 中检索嵌套实体。嵌套实体仅在它在会话中访问时才会被填充。 在 Spring Data 中,父实体的 REST 列表永远不会访问嵌套实体。当通过嵌套实体访问 URL 访问嵌套 LAZY 实体时,即。 /communities/GroupeSEB/posts 是访问的嵌套对象,并且该嵌套对象不是对象实例,而是对象的 LazyProxy,它将导致从 repo 中检索。 好的,可以从 repo 的 repo 层缓存中检索嵌套对象,但我认为您可以禁止嵌套实体/对象上的缓存。

    因此,如果有一种方法可以在 LazyProxy 实现中传递/检索分页信息,这可能会起作用。

    附:我从经验中知道他们,因为我在 @One2Many 和 @Many2One 之间进行了双向导航,为了防止 N+1 列出父母,我设置了 @ManyToOne(fetch = FetchType.LAZY) 然后在 repo 接口中覆盖相关的 findbyId() @NamedEntityGraph 在使用 @NamedEntityGraph 检索时强制嵌套到 EAGER。这并不直接适用于这个问题,但确实证明了在 spring 数据中,嵌套实体的检索是可控的。

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2015-08-30
      相关资源
      最近更新 更多