【问题标题】:How to force Hibernate to paginate over the same dataset it started the pagination with?如何强制 Hibernate 在开始分页的同一数据集上分页?
【发布时间】:2014-09-15 20:18:24
【问题描述】:

假设我的 article 数据库表中有 5 个元素:

+----+------+
| id | name |
+----+------+
|  1 | bb   |
|  2 | cc   |
|  3 | dd   |
|  4 | ee   |
|  5 | ff   |
+----+------+

如果我想用 2 元素页面对结果进行分页,我将使用以下查询:

Query query = session.createQuery("from Article order by name asc");
query.setFirstResult(pageNumber);
query.setMaxResults(2);

我看了第一页:

1/bb
2/cc

在我阅读第二页之前,另一个线程在表格中插入了一个新元素6/aa(按名称排序):

+----+------+
| id | name |
+----+------+
|  6 | aa   |
|  1 | bb   |
|  2 | cc   |
|  3 | dd   |
|  4 | ee   |
|  5 | ff   |
+----+------+

如果我阅读第二页,我会:

2/cc
3/dd

2/cc 元素将被读取两次:重复。

有什么方法可以强制 Hibernate 在开始分页时使用的同一数据集上分页?

PS:如果第二个线程执行update 查询(例如更改元素的名称,从而更改排序结果),也可能会出现这种情况,我也想避免这种情况。哦,我不是在寻找 if-already-read-then-remove-and-add-others-until-page-is-full 解决方案;)

【问题讨论】:

  • 如果更新改变了第一页的内容,那么拥有适当的第二页几乎没有什么好处,因为用户没有看到更新的第一页。

标签: java multithreading hibernate insert pagination


【解决方案1】:

我能看到的第一个解决方案是获取轻量级标题记录(id、标题等)并存储在用户上下文中。然后根据内存中的用户上下文创建分页。例如,这样的上下文可以保存在 http 会话中。

第二种解决方案是记住用户开始浏览/搜索时的时间戳,并在 HQL 中附加附加条件: where createdDate

也许这会有所帮助。

【讨论】:

  • 虽然您的第一个提议由于我实际拥有的大量记录而无法满足我的需求,但第二个可能是一个很好的解决方案。很奇怪,Hibernate 本身并没有提供这样的功能。
猜你喜欢
  • 2013-02-13
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 1970-01-01
相关资源
最近更新 更多