Spring Data Data中的分页用于嵌套资源

访问以下url时,我会得到分页作为回应

/api/userPosts/ { "_links" : { "self" : { "href" : "/api/userPosts{?page,size,sort}", "templated" : true }, "next" : { "href" : api/userPosts?page=1&size=20{&sort}", "templated" : true } }, "_embedded" : { "userPosts" : [ { ... 

但是,在访问以下URL时,Spring Data REST没有开箱即用的分页 –

 /api/users/4/userPosts { "_embedded" : { "userPosts" : [ { 

UserRepository和UserPostRepository都是具有分页的JPARepository。 因此,第二个URL导致GC开销超出错误,因为返回的结果的行数很大。

 @RepositoryRestResource(excerptProjection = UserProjection.class) public interface UserRepository extends BaseRepository, UserRepositoryCustom { } public interface UserPostRepository extends BaseRepository { } @NoRepositoryBean public interface BaseRepository extends JpaRepository, QueryDslPredicateExecutor { } 

是否也可以使用第二个URL进行分页?

简短的回答:不。绝对不是。

更长的痛苦回答:是的。 通过重写Spring Data,JPA和Hibernate的大部分内容。 问题的核心是,当您请求嵌套实体(集合与否)时,嵌套实体不是来自存储库的查询。 但是是从实体返回。 Spring Data / JPA中没有用于分页的机制

Spring REST中的/ api / users / 4 / userPosts请求基本上是这样的:

 User user = userRepository.findOne(4); return user.userPosts; 

因此,检索user.userPosts是对嵌套实体的Eager或Lazy引用,并且无法对其进行分页。

最简单,唯一的解决方案是:1。创建Spring Data搜索查询:UserPostRepository.findByUserId(Long id,Pagination pa)2。创建自定义Spring MVC控制器进行映射

  @Get("/api/users/{id}/userPosts") public Page getUserPostsByUserId(Long id, Pagination pagi) { return userPostRepository.findByUserId(id, pagi); 
  1. 重要! 你不能! 将user.userPosts注释为嵌套在User实体中或请求映射将发生冲突。
  2. 如果您想要在用户实体JSON中为此路径导航超链接,则需要自定义处理用户实体JSON创建。 它的文档很少,并且没有一个示例涵盖了您需要探索的确切用例。