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

时间:2014-10-19 15:11:54

标签: java spring spring-data spring-data-rest

访问以下网址时,我会在回复中获得分页

/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<User, Integer>, UserRepositoryCustom {

}

public interface UserPostRepository extends BaseRepository<UserPost, Long> {

}


@NoRepositoryBean
public interface BaseRepository<T, N extends Serializable> extends JpaRepository<T, N>, QueryDslPredicateExecutor<T> {

}

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

1 个答案:

答案 0 :(得分:0)

简短而痛苦的回答:不,绝对不是。

更多甚至更痛苦的答案:是的。通过重写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<UserPost> getUserPostsByUserId(Long id, Pagination pagi) {
     return userPostRepository.findByUserId(id, pagi);
  1. 重要!你不能!将user.userPosts注释为嵌套在User实体中,否则请求映射将发生冲突。
  2. 如果要在用户实体JSON中为此路径的导航超链接,则需要 用户实体JSON创建的自定义处理。它的文献记录不多,没有一个示例涵盖您需要探索的确切用例。