Как сделать пейджинг с коллекциями @OneToMany

Предположим, что у меня есть объект 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);

Можно ли эмулировать динамический пейджинг с коллекциями @OneToMany поверх JPA, или нам нужно полностью переписать механизм ассоциации JPA? (например, создать тип коллекции PersistentList, который мог бы управлять поиском, сортировкой и поиском).

P.S.: Недавно я нашел Play! Framework использует очень интересную библиотеку поверх JPA: 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 будут иметь методы fetch(), from(), которые косвенно относятся к JPAQuery.

Но я не знаю, признает ли Hibernate/JPA это или мешает ему.

Ответы

Ответ 1

Можно ли эмулировать динамический пейджинг с коллекциями @OneToMany поверх JPA (...)

Не поддерживается. Стандартный подход заключается в использовании запроса JPQL для извлечения комментариев для данного сообщения и использования Query#setFirstResult(int) и Query#setMaxResults(int).

С моей первой мыслью мы могли бы создать подкласс List, (...). Но я не знаю, признает ли Hibernate/JPA это или мешает ему.

Очевидно, что это не будет без патча тяжелого, чтобы резко изменить поведение по умолчанию.

Ответ 2

Я думаю, что "правильный" способ может быть больше похож:

@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);