Как сделать пейджинг с коллекциями @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);