【问题标题】:How can I do paging with @OneToMany collections如何使用 @OneToMany 集合进行分页
【发布时间】:2011-04-27 14:34:41
【问题描述】:

假设我有一个 Post 实体和一个 Comment 实体以及一对多关系:

@Entity class Post {
    ...
    @OneToMany
    List<Comment> comments;
    ...
}

如何实现这样的分页:

Post post = //Find the post.
return post.getComments().fetch(100, 10); // Find the 11th page (page size 10);

是否可以在 JPA 之上使用 @OneToMany 集合来模拟动态分页, 还是我们必须完全重写 JPA 的关联机制? (例如,创建一个可以管理分页、排序和搜索的 PersistentList 集合类型)。

P.S.:我最近发现了 Play!框架在 JPA 之上使用了一个非常有趣的库:Siena。 Siena 非常易于使用,并且是在 JPA/Hibernate 之上的一个很好的抽象。但我找不到如何使用它的关联进行分页。

更新:

Play 框架有一个类似于 Django 的查询语法:

Post.findAll().from(100).fetch(10);  // paging

在哪里

Post.findAll() 

将返回一个 JPAQuery 对象,Play 中自定义的查询类型。

但是有关联的集合,例如:

Post.comments

只会返回一个不支持分页或其他查询的列表。

我想知道如何扩展它,以便

Post.comments

还会返回一个 JPAQuery 对象或类似对象,然后您可以在“查询”集合上进行查询:

Post.comments.from(100).fetch(10);

或插入一个新评论而不实际获取任何 cmets:

Post.comments.add(new Comment(...));

我的第一个想法是,我们可以创建一个 List 的子类,那么 Post 类会变成:

@Entity class Post {
    ...
    @OneToMany
    QueryList<Comment> comments;
    ...
}

并且 QueryList 将具有间接到 JPAQuery 的 fetch()、from() 方法。

但我不知道 Hibernate/JPA 是否会认识到这一点,或者会干扰它。

【问题讨论】:

    标签: java hibernate jpa playframework siena


    【解决方案1】:

    是否可以在 JPA 之上使用 @OneToMany 集合来模拟动态分页(...)

    不支持。标准方法是使用 JPQL 查询来检索给定帖子的 cmets,并使用 Query#setFirstResult(int)Query#setMaxResults(int)

    我的第一个想法是,我们可以创建一个 List 的子类,(...)。但我不知道 Hibernate/JPA 是否会认识到这一点,或者会干扰它。

    如果没有 heavy 补丁显然不会彻底改变默认行为。

    【讨论】:

    • 顺便说一句。我发现 Hibernate 将“拦截”@OneToMany 集合,并将其间接到查询中。那么是否可以使用 Hibernate 识别的自定义集合类型(例如 @OneToMany LazyQueryList,它具有 fetch(start, offset) 方法)“插入”Hibernate 系统?
    • @Visus 应该可以patch Hibernate,这与插件机制有很大不同,这不会是一个小补丁。如果您决定朝这个方向发展,祝您好运。
    • 感谢您的澄清。我是hibernate的新手,沉重的补丁绝对超出了我的能力。但我仍然坚持如何有效地使用关联。在对另一个问题的回答中,我看到您以不好的方式谈论使用休眠的项目-“不使用关联,因为它们害怕“获取整个数据库””。我真的很想知道如何不检索整个集合。或者,在为集合手动创建 JPQL 查询的情况下,这是否意味着我们仅将关联集合用于映射?我们如何将它们设置回 Post.cmets?
    • I'd really like to know how NOT to retrieve a whole collection 让它变得懒惰,或者甚至EXTRA 懒惰。 Or, in the case of manually creating JPQL queries for the collection, does that mean we use the association collection only for the mapping?也用于查询。
    • 所以我猜当集合很小的时候,就用 Post.getComments();当它可能很大时,避免使用 Post.getComments() 并进行另一个查询(如果需要,分页),并独立使用结果列表。这是正确的做法吗?
    【解决方案2】:

    我认为“正确”的方式可能更像:

    @Entity
    class Post {
        ...
    
        public GenericModel.JPAQuery getComments() {
            return Comment.find("post_id = ?", post_id);
        }
    }
    

    然后在JPAQuery 中使用fetch methods 之一:

    // fetch first page of results, 25 results per page
    post.getComments().fetch(1,25);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      • 2021-04-18
      • 2017-08-01
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多