英文:
Spring JPA/Hibernate returns random last page?
问题
我最近将一个服务从:
- JDK8 -> JDK11
- Spring Boot 1.5 -> Spring Boot 2.3
从那以后,一个集成测试以一种奇怪的方式失败了,当执行查询(分页)时出现问题。从100个结果中,即5页,第5页总是随机选择。
结果看起来像这样:
第0页(ids [0, 19])
[SomeObject@... 'inttest_log_device_0', ...]
[SomeObject@... 'inttest_log_device_1', ...]
[SomeObject@... 'inttest_log_device_2', ...]
[SomeObject@... 'inttest_log_device_3', ...]
[SomeObject@... 'inttest_log_device_4', ...]
[SomeObject@... 'inttest_log_device_5', ...]
[SomeObject@... 'inttest_log_device_6', ...]
[SomeObject@... 'inttest_log_device_7', ...]
[SomeObject@... 'inttest_log_device_8', ...]
[SomeObject@... 'inttest_log_device_9',...]
[SomeObject@... 'inttest_log_device_10', ...]
[SomeObject@... 'inttest_log_device_11', ...]
[SomeObject@... 'inttest_log_device_12', ...]
[SomeObject@... 'inttest_log_device_13', ...]
[SomeObject@... 'inttest_log_device_14', ...]
[SomeObject@... 'inttest_log_device_15', ...]
[SomeObject@... 'inttest_log_device_16', ...]
[SomeObject@... 'inttest_log_device_17', ...]
[SomeObject@... 'inttest_log_device_18', ...]
[SomeObject@... 'inttest_log_device_19', ...]
页面1-3继续如上。
然而最后一页(#4)不同(预期ids [80, 99]):
[SomeObject@... 'inttest_log_device_25', ...]
[SomeObject@... 'inttest_log_device_94', ...]
[SomeObject@... 'inttest_log_device_0', ...]
[SomeObject@... 'inttest_log_device_31', ...]
[SomeObject@... 'inttest_log_device_62', ...]
[SomeObject@... 'inttest_log_device_13', ...]
[SomeObject@... 'inttest_log_device_69', ...]
[SomeObject@... 'inttest_log_device_33', ...]
[SomeObject@... 'inttest_log_device_64', ...]
[SomeObject@... 'inttest_log_device_52', ...]
[SomeObject@... 'inttest_log_device_86', ...]
[SomeObject@... 'inttest_log_device_24', ...]
[SomeObject@... 'inttest_log_device_16', ...]
[SomeObject@... 'inttest_log_device_22', ...]
[SomeObject@... 'inttest_log_device_89', ...]
[SomeObject@... 'inttest_log_device_50', ...]
[SomeObject@... 'inttest_log_device_57', ...]
[SomeObject@... 'inttest_log_device_92', ...]
[SomeObject@... 'inttest_log_device_29', ...]
[SomeObject@... 'inttest_log_device_15', ...]
执行的代码是:
someRepository.findAll(predicate, pageable);
其中 repository 简单地扩展了 Spring 的 JpaRepository
和 QuerydslPredicateExecutor
。predicate
是一个带有一些过滤条件的 BooleanBuilder
。
此代码此前一直运行得非常完美。但自从升级后开始出问题。
英文:
I have recently upgraded a service from:
- JDK8 -> JDK11
- Spring Boot 1.5 -> Spring Boot 2.3
Since then, an integration test fails in a weird way, such that when a query is executed (pageable). From the 100 results i.e. 5 pages, the 5th page is always a random selection.
The result looks looks like this:
Page 0 (ids [0, 19])
[SomeObject@... 'inttest_log_device_0', ...]
[SomeObject@... 'inttest_log_device_1', ...]
[SomeObject@... 'inttest_log_device_2', ...]
[SomeObject@... 'inttest_log_device_3', ...]
[SomeObject@... 'inttest_log_device_4', ...]
[SomeObject@... 'inttest_log_device_5', ...]
[SomeObject@... 'inttest_log_device_6', ...]
[SomeObject@... 'inttest_log_device_7', ...]
[SomeObject@... 'inttest_log_device_8', ...]
[SomeObject@... 'inttest_log_device_9',...]
[SomeObject@... 'inttest_log_device_10', ...]
[SomeObject@... 'inttest_log_device_11', ...]
[SomeObject@... 'inttest_log_device_12', ...]
[SomeObject@... 'inttest_log_device_13', ...]
[SomeObject@... 'inttest_log_device_14', ...]
[SomeObject@... 'inttest_log_device_15', ...]
[SomeObject@... 'inttest_log_device_16', ...]
[SomeObject@... 'inttest_log_device_17', ...]
[SomeObject@... 'inttest_log_device_18', ...]
[SomeObject@... 'inttest_log_device_19', ...]
Pages 1-3 continue as above.
However the last page (#4) is different (expected ids [80, 99]) :
[SomeObject@... 'inttest_log_device_25', ...]
[SomeObject@... 'inttest_log_device_94', ...]
[SomeObject@... 'inttest_log_device_0', ...]
[SomeObject@... 'inttest_log_device_31', ...]
[SomeObject@... 'inttest_log_device_62', ...]
[SomeObject@... 'inttest_log_device_13', ...]
[SomeObject@... 'inttest_log_device_69', ...]
[SomeObject@... 'inttest_log_device_33', ...]
[SomeObject@... 'inttest_log_device_64', ...]
[SomeObject@... 'inttest_log_device_52', ...]
[SomeObject@... 'inttest_log_device_86', ...]
[SomeObject@... 'inttest_log_device_24', ...]
[SomeObject@... 'inttest_log_device_16', ...]
[SomeObject@... 'inttest_log_device_22', ...]
[SomeObject@... 'inttest_log_device_89', ...]
[SomeObject@... 'inttest_log_device_50', ...]
[SomeObject@... 'inttest_log_device_57', ...]
[SomeObject@... 'inttest_log_device_92', ...]
[SomeObject@... 'inttest_log_device_29', ...]
[SomeObject@... 'inttest_log_device_15', ...]
The executed code is:
someRepository.findAll(predicate, pageable);
Where the repository simply extends Spring's JpaRepository
and QuerydslPredicateExecutor
. The predicate
is a BooleanBuilder
with some filter criteria.
The code furthermore always worked perfectly well. It just started making problems once I've upgraded.
答案1
得分: 3
没有明确的排序,基本上你就要看数据库管理系统返回什么。使用分页时,你应该始终有明确的排序。
你可以通过向传递的“Pageable”添加“Sort”来实现这一点。
Pageable pageable = PageRequest.of(0, 1, Direction.ASC, "id");
这样做应该能达到效果。
英文:
Without an explicit ordering, you are basically at the perils of DBMS what it returns. When using paging you should always have an explicit ordering.
You can do this by adding a Sort
to the Pageable
you pass in.
Pageable pageable = PageRequest.of(0, 1, Direction.ASC, "id);
Something like that should do the trick.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论