Skip to content

Commit dca68eb

Browse files
committed
Stateless session should use batching
In Hibernate ORM and Reactive, the stateless session ignore the batch size property. The reason is that the stateless session execute queries immediately and does not store the entities to execute a batch update later. To enable batching, we need to use the `updateMultiple` method instead. It will use the size of the list as batch value.
1 parent f5113b6 commit dca68eb

3 files changed

Lines changed: 15 additions & 18 deletions

File tree

frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,15 @@ public Uni<Void> createData() {
3737
});
3838
}
3939

40-
public Uni<List<World>> update(Mutiny.Session session, List<World> worlds) {
41-
return session
42-
.setBatchSize(worlds.size())
43-
.flush()
44-
.map(v -> worlds);
40+
public Uni<List<World>> update(Mutiny.StatelessSession session, List<World> worlds) {
41+
return session.updateMultiple(worlds).replaceWith(worlds);
4542
}
4643

4744
public Uni<List<World>> findStateless(int count) {
4845
return inStatelessSession(session -> findStateless(session, count));
4946
}
5047

51-
private Uni<List<World>> findStateless(Mutiny.StatelessSession s, int count) {
48+
public Uni<List<World>> findStateless(Mutiny.StatelessSession s, int count) {
5249
//The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs
5350
// as one single operation as Hibernate is too smart and will switch to use batched loads automatically.
5451
// Hence, use this awkward alternative:

frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,14 @@ public Uni<Void> createData() {
4444
return worldRepository.createData();
4545
}
4646

47-
private Uni<List<World>> randomWorldsForWrite(Mutiny.Session session, int count) {
48-
return worldRepository.findManaged(session, count);
47+
private Uni<List<World>> randomWorldsForWrite(Mutiny.StatelessSession session, int count) {
48+
return worldRepository.findStateless(session, count);
4949
}
5050

5151
@GET
5252
@Path("updates")
5353
public Uni<List<World>> updates(@QueryParam("queries") String queries) {
54-
return worldRepository.inSession(session -> {
55-
56-
session.setFlushMode(FlushMode.MANUAL);
57-
54+
return worldRepository.inStatelessSession(session -> {
5855
Uni<List<World>> worlds = randomWorldsForWrite(session, parseQueryCount(queries));
5956
return worlds.flatMap(worldsCollection -> {
6057
final LocalRandom localRandom = Randomizer.current();
@@ -66,7 +63,6 @@ public Uni<List<World>> updates(@QueryParam("queries") String queries) {
6663
//the verification:
6764
w.setRandomNumber(localRandom.getNextRandomExcluding(previousRead));
6865
} );
69-
7066
return worldRepository.update(session, worldsCollection);
7167
});
7268
});

frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.quarkus.benchmark.repository;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
36
import io.quarkus.benchmark.model.World;
47
import io.quarkus.benchmark.utils.LocalRandom;
58
import io.quarkus.benchmark.utils.Randomizer;
@@ -53,21 +56,22 @@ public World[] loadNWorlds(final int count) {
5356

5457
public World[] updateNWorlds(final int count) {
5558
//We're again forced to use the "individual load" pattern by the rules:
56-
final World[] list = loadNWorlds(count);
59+
final World[] worlds = loadNWorlds(count);
60+
final List<World> worldList = new ArrayList<>(worlds.length);
5761
final LocalRandom random = Randomizer.current();
5862
try (StatelessSession s = sf.openStatelessSession()) {
59-
s.setJdbcBatchSize(count);
60-
for (World w : list) {
63+
for (World w : worlds) {
6164
//Read the one field, as required by the following rule:
6265
// # vi. At least the randomNumber field must be read from the database result set.
6366
final int previousRead = w.getRandomNumber();
6467
//Update it, but make sure to exclude the current number as Hibernate optimisations would otherwise
6568
// skip the write operation:
6669
w.setRandomNumber(random.getNextRandomExcluding(previousRead));
67-
s.update(w);
70+
worldList.add(w);
6871
}
72+
s.updateMultiple(worldList);
6973
}
70-
return list;
74+
return worlds;
7175
}
7276

7377
}

0 commit comments

Comments
 (0)