17

假设我有一个 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 集合类型)。

PS:我最近发现了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);

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

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

我的第一个想法是,我们可以创建一个 List 的子类,然后 Post 类将变为:

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

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

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

4

2 回答 2

8

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

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

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

显然,如果没有大量补丁来彻底改变默认行为,它就不会发生。

于 2010-10-19T17:35:12.603 回答
4

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

@Entity
class Post {
    ...

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

然后使用以下fetch 方法之一JPAQuery

// fetch first page of results, 25 results per page
post.getComments().fetch(1,25);
于 2011-01-21T22:41:42.487 回答