From dcd22360b769020223361c51c6c8e691cce46c3b Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 15 Mar 2024 14:14:06 +0100 Subject: [PATCH] Fix Jdbc benchmark failures Spring Boot 3s Datasource autoconfiguration backs off when R2DBC is present. Therefore a Datasource has to constructed explicitly. And other autoconfigurations which would collide with JDBC had to be disabled. --- benchmark/relational/readme.adoc | 14 +++++- .../microbenchmark/jdbc/BenchmarkMain.java | 13 ++++++ .../data/microbenchmark/jdbc/Book.java | 2 + .../microbenchmark/jdbc/JdbcBenchmark.java | 3 +- .../data/microbenchmark/jdbc/JdbcFixture.java | 44 ++++++++++++++++++- .../application-h2-in-memory.properties | 7 ++- .../main/resources/application-h2.properties | 6 ++- .../resources/application-jdbc.properties | 1 + .../resources/application-postgres.properties | 11 +++-- .../relational/src/main/resources/data-h2.sql | 16 +++---- 10 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/BenchmarkMain.java diff --git a/benchmark/relational/readme.adoc b/benchmark/relational/readme.adoc index a188d6b..01a21a5 100644 --- a/benchmark/relational/readme.adoc +++ b/benchmark/relational/readme.adoc @@ -28,8 +28,18 @@ There are different flavors of those operations to measure the impact of differe The benchmarks are run against the following databases: - In-memory H2 -- A locally running H2 (port 9092, database name `benchmark`, user `sa`, empty password) -- A locally running Postgres (port 5432, database name `benchmark`, no user, no password) +- A locally running H2 (port 9092, database name `benchmark`, user `sa`, empty password). + You may start such a server by running ++ +``` +java -cp ~/.m2/repository/com/h2database/h2/2.2.224/h2-2.2.224.jar org.h2.tools.Server -ifNotExists +``` +assuming you have a local maven repo in the default location. +- A locally running Postgres (port 5455, database name `benchmark`, user: postgres, password: secret). You may start such a server by running ++ +``` +docker run --name myPostgresDb -p 5455:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=benchmark -d postgres +``` The settings can be adapted by tweaking corresponding `application-$database.properties` file in `src/main/resources`. \ No newline at end of file diff --git a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/BenchmarkMain.java b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/BenchmarkMain.java new file mode 100644 index 0000000..05181f9 --- /dev/null +++ b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/BenchmarkMain.java @@ -0,0 +1,13 @@ +package org.springframework.data.microbenchmark.jdbc; + +import org.openjdk.jmh.infra.Blackhole; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class BenchmarkMain { + public static void main(String[] args) throws Exception { + JdbcBenchmark jdbcBenchmark = new JdbcBenchmark(); + jdbcBenchmark.profile = "postgres"; + jdbcBenchmark.setUp(); + jdbcBenchmark.convertWithSpringData(new Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous.")); + } +} diff --git a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/Book.java b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/Book.java index 7b839bf..c24e7ae 100644 --- a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/Book.java +++ b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/Book.java @@ -19,12 +19,14 @@ import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; /** * @author Oliver Drotbohm */ @Data @AllArgsConstructor +@Table public class Book { private @Id Long id; diff --git a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcBenchmark.java b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcBenchmark.java index af55a8a..d143b11 100644 --- a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcBenchmark.java +++ b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcBenchmark.java @@ -44,7 +44,7 @@ public class JdbcBenchmark extends AbstractMicrobenchmark { private static final String BY_TITLE_SQL = "SELECT id, title, pages FROM Book where title = ?"; - @Param({ "postgres", "h2-in-memory", "h2" }) String profile; + @Param({ /*"postgres",*/ "h2-in-memory", /*"h2"*/ }) String profile; JdbcOperations operations; RowMapper bookMapper; @@ -53,7 +53,6 @@ public class JdbcBenchmark extends AbstractMicrobenchmark { Set columns; HashMap values; - @Setup @SuppressWarnings("unchecked") public void setUp() { diff --git a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcFixture.java b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcFixture.java index 254eea7..3c2f4d5 100644 --- a/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcFixture.java +++ b/benchmark/relational/src/main/java/org/springframework/data/microbenchmark/jdbc/JdbcFixture.java @@ -19,11 +19,22 @@ import lombok.Getter; import java.lang.reflect.Field; +import org.h2.jdbcx.JdbcDataSource; +import org.postgresql.ds.PGSimpleDataSource; import org.springframework.aop.framework.Advised; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.data.jdbc.core.JdbcAggregateTemplate; import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository; import org.springframework.data.mapping.callback.EntityCallback; @@ -32,6 +43,8 @@ import org.springframework.data.microbenchmark.FixtureUtils; import org.springframework.jdbc.core.RowMapper; import org.springframework.util.ReflectionUtils; +import javax.sql.DataSource; + /** * Test fixture for JDBC and Spring Data JDBC benchmarks. * @@ -73,8 +86,35 @@ class JdbcFixture { } } - @SpringBootApplication - static class JdbcApplication {} + @SpringBootApplication( + exclude = { + R2dbcAutoConfiguration.class, + R2dbcDataAutoConfiguration.class, + R2dbcRepositoriesAutoConfiguration.class, + R2dbcTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class + } + ) + static class JdbcApplication { + + @Bean + @Profile({"h2","h2-in-memory"}) + @ConfigurationProperties(prefix = "spring.datasource") + DataSource dataSourceH2() { + return new JdbcDataSource(); + } + + @Bean + @Profile({"postgres"}) + @ConfigurationProperties(prefix = "spring.datasource") + DataSource dataSourcePostgres() { + PGSimpleDataSource dataSource = new PGSimpleDataSource(); + return dataSource; + } + + } + + enum NoOpApplicationEventPublisher implements ApplicationEventPublisher { diff --git a/benchmark/relational/src/main/resources/application-h2-in-memory.properties b/benchmark/relational/src/main/resources/application-h2-in-memory.properties index 09e4bd6..5d32eba 100644 --- a/benchmark/relational/src/main/resources/application-h2-in-memory.properties +++ b/benchmark/relational/src/main/resources/application-h2-in-memory.properties @@ -1,3 +1,6 @@ -spring.datasource.platform=h2 - +spring.datasource.url=jdbc:h2:mem:benchmark;DB_CLOSE_DELAY=-1 +spring.sql.init.platform=h2 spring.r2dbc.platform=h2 + + +logging.level.org.springframework.boot.autoconfigure=DEBUG \ No newline at end of file diff --git a/benchmark/relational/src/main/resources/application-h2.properties b/benchmark/relational/src/main/resources/application-h2.properties index f977da2..b58c88d 100644 --- a/benchmark/relational/src/main/resources/application-h2.properties +++ b/benchmark/relational/src/main/resources/application-h2.properties @@ -1,11 +1,13 @@ spring.datasource.url=jdbc:h2:tcp://localhost:9092/~/benchmark spring.datasource.username=sa spring.datasource.password= -spring.datasource.platform=h2 -spring.datasource.initialization-mode=always +spring.sql.init.platform=h2 +spring.sql.init.mode=always spring.r2dbc.url=r2dbc:h2:tcp://localhost:9092/~/benchmark spring.r2dbc.username=sa spring.r2dbc.password= spring.r2dbc.platform=h2 spring.r2dbc.initialization-mode=always + +logging.level.org.springframework.boot.autoconfigure=DEBUG \ No newline at end of file diff --git a/benchmark/relational/src/main/resources/application-jdbc.properties b/benchmark/relational/src/main/resources/application-jdbc.properties index d580454..6b0661b 100644 --- a/benchmark/relational/src/main/resources/application-jdbc.properties +++ b/benchmark/relational/src/main/resources/application-jdbc.properties @@ -1 +1,2 @@ spring.data.jpa.repositories.enabled=false + diff --git a/benchmark/relational/src/main/resources/application-postgres.properties b/benchmark/relational/src/main/resources/application-postgres.properties index 59a7924..fda64ac 100644 --- a/benchmark/relational/src/main/resources/application-postgres.properties +++ b/benchmark/relational/src/main/resources/application-postgres.properties @@ -1,9 +1,12 @@ -spring.datasource.url=jdbc:postgresql://localhost:5432/benchmark -spring.datasource.platform=postgres -spring.datasource.initialization-mode=always +spring.datasource.url=jdbc:postgresql://localhost:5455/benchmark +# this is intentionally non standard property user instead of username, since we are using PGSimpleDatasource, which has a user, but no username property +spring.datasource.user=postgres +spring.datasource.password=secret +spring.sql.init.platform=postgres +spring.sql.init.mode=always spring.r2dbc.url=r2dbc:postgresql://localhost:5432/benchmark spring.r2dbc.platform=postgres spring.r2dbc.username=postgres -spring.r2dbc.password= +spring.r2dbc.password=secret spring.r2dbc.initialization-mode=always diff --git a/benchmark/relational/src/main/resources/data-h2.sql b/benchmark/relational/src/main/resources/data-h2.sql index f2324d6..05627f4 100644 --- a/benchmark/relational/src/main/resources/data-h2.sql +++ b/benchmark/relational/src/main/resources/data-h2.sql @@ -1,8 +1,8 @@ -INSERT INTO Book VALUES (null, 'title0', 0); -INSERT INTO Book VALUES (null, 'title1', 1); -INSERT INTO Book VALUES (null, 'title2', 2); -INSERT INTO Book VALUES (null, 'title3', 3); -INSERT INTO Book VALUES (null, 'title4', 4); -INSERT INTO Book VALUES (null, 'title5', 5); -INSERT INTO Book VALUES (null, 'title6', 6); -INSERT INTO Book VALUES (null, 'title7', 7); +INSERT INTO Book (title, pages) VALUES ('title1', 1); +INSERT INTO Book (title, pages) VALUES ('title0', 0); +INSERT INTO Book (title, pages) VALUES ('title2', 2); +INSERT INTO Book (title, pages) VALUES ('title3', 3); +INSERT INTO Book (title, pages) VALUES ('title4', 4); +INSERT INTO Book (title, pages) VALUES ('title5', 5); +INSERT INTO Book (title, pages) VALUES ('title6', 6); +INSERT INTO Book (title, pages) VALUES ('title7', 7);