diff --git a/frameworks/Java/quarkus/README.md b/frameworks/Java/quarkus/README.md index 0bced001077..2925bb9e35c 100644 --- a/frameworks/Java/quarkus/README.md +++ b/frameworks/Java/quarkus/README.md @@ -13,6 +13,10 @@ There are currently 2 implementations: ./tfb --mode verify --test quarkus quarkus-hibernate-reactive +After the database container image is created, it can be started independently. + + docker run -d --name tfb-database -e POSTGRES_DB=hello_world -e POSTGRES_PASSWORD=benchmarkdbpass -e POSTGRES_USER=benchmarkdbuser -p 5432:5432 techempower/postgres:latest + ## Versions * [Java OpenJDK 17](http://openjdk.java.net/) diff --git a/frameworks/Java/quarkus/pom.xml b/frameworks/Java/quarkus/pom.xml index 26dcb870c26..9e2820c65dd 100644 --- a/frameworks/Java/quarkus/pom.xml +++ b/frameworks/Java/quarkus/pom.xml @@ -8,15 +8,15 @@ pom - 3.14.0 - 21 + 3.15.0 + 25 UTF-8 UTF-8 quarkus-bom io.quarkus - 3.21.2 + 3.32.2 true - 3.5.2 + 3.5.4 0.0.26.Final 1.3.0 @@ -61,6 +61,16 @@ + + + + + + kr.motd.maven + os-maven-plugin + 1.7.1 + + ${quarkus.platform.group-id} @@ -81,9 +91,7 @@ maven-compiler-plugin ${compiler-plugin.version} - - -parameters - + true diff --git a/frameworks/Java/quarkus/quarkus-hibernate-reactive.dockerfile b/frameworks/Java/quarkus/quarkus-hibernate-reactive.dockerfile index 861dd3b042a..6fad2093a60 100644 --- a/frameworks/Java/quarkus/quarkus-hibernate-reactive.dockerfile +++ b/frameworks/Java/quarkus/quarkus-hibernate-reactive.dockerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/openjdk-21:1.22 as maven +FROM registry.access.redhat.com/ubi9/openjdk-25:1.24 as maven ENV LANGUAGE='en_US:en' WORKDIR /quarkus @@ -29,7 +29,7 @@ WORKDIR /quarkus/$MODULE RUN mvn package -B -q WORKDIR /quarkus -FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:1.22 +FROM registry.access.redhat.com/ubi9/openjdk-25-runtime:1.24 ENV LANGUAGE='en_US:en' WORKDIR /quarkus ENV MODULE=resteasy-reactive-hibernate-reactive diff --git a/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile b/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile index 21e918be45c..fc9d914e7d0 100644 --- a/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile +++ b/frameworks/Java/quarkus/quarkus-reactive-routes-pgclient.dockerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/openjdk-21:1.22 as maven +FROM registry.access.redhat.com/ubi9/openjdk-25:1.24 as maven ENV LANGUAGE='en_US:en' WORKDIR /quarkus @@ -29,7 +29,7 @@ WORKDIR /quarkus/$MODULE RUN mvn package -B -q WORKDIR /quarkus -FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:1.22 +FROM registry.access.redhat.com/ubi9/openjdk-25-runtime:1.24 ENV LANGUAGE='en_US:en' WORKDIR /quarkus ENV MODULE=reactive-routes-pgclient diff --git a/frameworks/Java/quarkus/quarkus-vertx.dockerfile b/frameworks/Java/quarkus/quarkus-vertx.dockerfile index 6969bc6d7ba..09865d3d086 100644 --- a/frameworks/Java/quarkus/quarkus-vertx.dockerfile +++ b/frameworks/Java/quarkus/quarkus-vertx.dockerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/openjdk-21:1.22 as maven +FROM registry.access.redhat.com/ubi9/openjdk-25:1.24 as maven ENV LANGUAGE='en_US:en' WORKDIR /quarkus @@ -29,7 +29,7 @@ WORKDIR /quarkus/$MODULE RUN mvn package -B -q WORKDIR /quarkus -FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:1.22 +FROM registry.access.redhat.com/ubi9/openjdk-25-runtime:1.24 ENV LANGUAGE='en_US:en' WORKDIR /quarkus ENV MODULE=vertx diff --git a/frameworks/Java/quarkus/quarkus.dockerfile b/frameworks/Java/quarkus/quarkus.dockerfile index 40ec7a4ded7..b3eb400251e 100644 --- a/frameworks/Java/quarkus/quarkus.dockerfile +++ b/frameworks/Java/quarkus/quarkus.dockerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/openjdk-21:1.22 as maven +FROM registry.access.redhat.com/ubi9/openjdk-25:1.24 as maven ENV LANGUAGE='en_US:en' WORKDIR /quarkus @@ -29,7 +29,7 @@ WORKDIR /quarkus/$MODULE RUN mvn package -B -q WORKDIR /quarkus -FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:1.22 +FROM registry.access.redhat.com/ubi9/openjdk-25-runtime:1.24 ENV LANGUAGE='en_US:en' WORKDIR /quarkus ENV MODULE=resteasy-reactive-hibernate diff --git a/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml b/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml index 599183b4656..a976941d583 100644 --- a/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml +++ b/frameworks/Java/quarkus/reactive-routes-pgclient/pom.xml @@ -40,7 +40,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre io.netty @@ -75,7 +75,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml index 8948c5ffb06..165e4e59d36 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/pom.xml @@ -44,7 +44,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre io.netty diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java index 90130a91022..468c35593ea 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java @@ -24,31 +24,26 @@ public Uni createData() { return inSession(s -> { final LocalRandom random = Randomizer.current(); int MAX = 10000; - Uni[] unis = new Uni[MAX]; + Uni loop = Uni.createFrom().voidItem(); for (int i = 0; i < MAX; i++) { final World world = new World(); world.setId(i + 1); world.setRandomNumber(random.getNextRandom()); - unis[i] = s.persist(world).map(v -> null); + loop = loop.call(() -> s.persist(world)); } - return Uni.combine().all().unis(unis).with(l -> null) - .flatMap(v -> s.flush()) - .map(v -> null); + return loop.call(s::flush); }); } - public Uni> update(Mutiny.Session session, List worlds) { - return session - .setBatchSize(worlds.size()) - .flush() - .map(v -> worlds); + public Uni> update(Mutiny.StatelessSession session, List worlds) { + return session.updateMultiple(worlds).replaceWith(worlds); } public Uni> findStateless(int count) { return inStatelessSession(session -> findStateless(session, count)); } - private Uni> findStateless(Mutiny.StatelessSession s, int count) { + public Uni> findStateless(Mutiny.StatelessSession s, int count) { //The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs // as one single operation as Hibernate is too smart and will switch to use batched loads automatically. // Hence, use this awkward alternative: @@ -56,23 +51,9 @@ private Uni> findStateless(Mutiny.StatelessSession s, int count) { final List worlds = new ArrayList<>(count); Uni loopRoot = Uni.createFrom().voidItem(); for (int i = 0; i < count; i++) { - loopRoot = loopRoot.chain(() -> s.get(World.class, localRandom.getNextRandom()).invoke(worlds::add).replaceWithVoid()); + loopRoot = loopRoot.call(() -> s.get(World.class, localRandom.getNextRandom()).invoke(worlds::add)); } - return loopRoot.map(v -> worlds); - } - - public Uni> findManaged(Mutiny.Session s, int count) { - final List worlds = new ArrayList<>(count); - //The rules require individual load: we can't use the Hibernate feature which allows load by multiple IDs - // as one single operation as Hibernate is too smart and will switch to use batched loads. - // But also, we can't use "Uni#join" as we did in the above method as managed entities shouldn't use pipelining - - // so we also have to avoid Mutiny optimising things by establishing an explicit chain: - final LocalRandom localRandom = Randomizer.current(); - Uni loopRoot = Uni.createFrom().voidItem(); - for (int i = 0; i < count; i++) { - loopRoot = loopRoot.chain(() -> s.find(World.class, localRandom.getNextRandom()).invoke(worlds::add).replaceWithVoid()); - } - return loopRoot.map(v -> worlds); + return loopRoot.replaceWith(worlds); } public Uni findStateless() { diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java index c536e7033f2..c440f4c0114 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/java/io/quarkus/benchmark/resource/DbResource.java @@ -44,17 +44,14 @@ public Uni createData() { return worldRepository.createData(); } - private Uni> randomWorldsForWrite(Mutiny.Session session, int count) { - return worldRepository.findManaged(session, count); + private Uni> randomWorldsForWrite(Mutiny.StatelessSession session, int count) { + return worldRepository.findStateless(session, count); } @GET @Path("updates") public Uni> updates(@QueryParam("queries") String queries) { - return worldRepository.inSession(session -> { - - session.setFlushMode(FlushMode.MANUAL); - + return worldRepository.inStatelessSession(session -> { Uni> worlds = randomWorldsForWrite(session, parseQueryCount(queries)); return worlds.flatMap(worldsCollection -> { final LocalRandom localRandom = Randomizer.current(); @@ -66,7 +63,6 @@ public Uni> updates(@QueryParam("queries") String queries) { //the verification: w.setRandomNumber(localRandom.getNextRandomExcluding(previousRead)); } ); - return worldRepository.update(session, worldsCollection); }); }); diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties index df4d6512d35..29980229505 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate-reactive/src/main/resources/application.properties @@ -17,6 +17,8 @@ quarkus.hibernate-orm.second-level-caching-enabled=false #quarkus.vertx.storage=false +quarkus.hibernate-orm.log.sql=false + quarkus.log.console.enable=true quarkus.log.console.level=INFO quarkus.log.file.enable=false diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml b/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml index 5cd634dbea5..ea98cd58163 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/pom.xml @@ -44,7 +44,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre io.netty @@ -79,7 +79,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre diff --git a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java index a9c82fb1eec..a1e93d5ba58 100644 --- a/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java +++ b/frameworks/Java/quarkus/resteasy-reactive-hibernate/src/main/java/io/quarkus/benchmark/repository/WorldRepository.java @@ -1,18 +1,17 @@ package io.quarkus.benchmark.repository; +import java.util.ArrayList; +import java.util.List; + +import io.quarkus.benchmark.model.World; +import io.quarkus.benchmark.utils.LocalRandom; +import io.quarkus.benchmark.utils.Randomizer; import jakarta.inject.Inject; import jakarta.inject.Singleton; import jakarta.transaction.Transactional; - -import org.hibernate.FlushMode; -import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.StatelessSession; -import io.quarkus.benchmark.model.World; -import io.quarkus.benchmark.utils.LocalRandom; -import io.quarkus.benchmark.utils.Randomizer; - @Singleton public class WorldRepository { @@ -57,23 +56,22 @@ public World[] loadNWorlds(final int count) { public World[] updateNWorlds(final int count) { //We're again forced to use the "individual load" pattern by the rules: - final World[] list = loadNWorlds(count); + final World[] worlds = loadNWorlds(count); + final List worldList = new ArrayList<>(worlds.length); final LocalRandom random = Randomizer.current(); - try (Session s = sf.openSession()) { - s.setJdbcBatchSize(count); - s.setHibernateFlushMode(FlushMode.MANUAL); - for (World w : list) { + try (StatelessSession s = sf.openStatelessSession()) { + for (World w : worlds) { //Read the one field, as required by the following rule: // # vi. At least the randomNumber field must be read from the database result set. final int previousRead = w.getRandomNumber(); //Update it, but make sure to exclude the current number as Hibernate optimisations would otherwise // skip the write operation: w.setRandomNumber(random.getNextRandomExcluding(previousRead)); - s.update(w); + worldList.add(w); } - s.flush(); + s.updateMultiple(worldList); } - return list; + return worlds; } } diff --git a/frameworks/Java/quarkus/vertx/pom.xml b/frameworks/Java/quarkus/vertx/pom.xml index a5c6cdbcdde..07418ebf8a9 100644 --- a/frameworks/Java/quarkus/vertx/pom.xml +++ b/frameworks/Java/quarkus/vertx/pom.xml @@ -26,7 +26,7 @@ com.ongres.scram - client + scram-client io.quarkus @@ -40,7 +40,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre io.netty @@ -75,7 +75,7 @@ com.google.guava guava - 32.0.0-jre + 32.0.1-jre