From 879984d2b6dee01c49c14220aa9a8460e03ad5b7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 19 Jul 2023 15:10:09 +0200 Subject: [PATCH] Polishing. Push JDBC-specific simple types into JdbcPostgresDialect instead of having these in the top-level dialect that shouldn't be tied to any driver technology. Introduce profile to run Postgres tests only. --- spring-data-jdbc/pom.xml | 31 ++++++++++++++ .../data/jdbc/aot/JdbcRuntimeHints.java | 3 -- .../core/dialect/JdbcPostgresDialect.java | 40 +++++++++++++++++++ .../data/r2dbc/dialect/PostgresDialect.java | 7 +--- .../core/dialect/PostgresDialect.java | 39 +++++------------- 5 files changed, 81 insertions(+), 39 deletions(-) diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 32f9269501..a9d656f1d1 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -237,6 +237,37 @@ + + postgres + + + + org.apache.maven.plugins + maven-surefire-plugin + + + postgres-test + test + + test + + + + **/*IntegrationTests.java + + + **/*HsqlIntegrationTests.java + + + postgres + + + + + + + + all-dbs diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot/JdbcRuntimeHints.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot/JdbcRuntimeHints.java index 46daafb46d..79abb5db2b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot/JdbcRuntimeHints.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot/JdbcRuntimeHints.java @@ -16,7 +16,6 @@ package org.springframework.data.jdbc.aot; import java.util.Arrays; -import java.util.UUID; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; @@ -63,7 +62,5 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) for (Class simpleType : JdbcPostgresDialect.INSTANCE.simpleTypes()) { hints.reflection().registerType(TypeReference.of(simpleType), MemberCategory.PUBLIC_CLASSES); } - - hints.reflection().registerType(TypeReference.of(UUID.class.getName()), MemberCategory.PUBLIC_CLASSES); } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java index 03008725aa..ff57d1b563 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java @@ -23,9 +23,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import org.postgresql.core.Oid; import org.postgresql.jdbc.TypeInfoCache; @@ -46,11 +50,47 @@ public class JdbcPostgresDialect extends PostgresDialect implements JdbcDialect private static final JdbcPostgresArrayColumns ARRAY_COLUMNS = new JdbcPostgresArrayColumns(); + private static final Set> SIMPLE_TYPES; + + static { + + Set> simpleTypes = new HashSet<>(PostgresDialect.INSTANCE.simpleTypes()); + List simpleTypeNames = Arrays.asList( // + "org.postgresql.util.PGobject", // + "org.postgresql.geometric.PGpoint", // + "org.postgresql.geometric.PGbox", // + "org.postgresql.geometric.PGcircle", // + "org.postgresql.geometric.PGline", // + "org.postgresql.geometric.PGpath", // + "org.postgresql.geometric.PGpolygon", // + "org.postgresql.geometric.PGlseg" // + ); + simpleTypeNames.forEach(name -> ifClassPresent(name, simpleTypes::add)); + SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes); + } + + @Override + public Set> simpleTypes() { + return SIMPLE_TYPES; + } + @Override public JdbcArrayColumns getArraySupport() { return ARRAY_COLUMNS; } + /** + * If the class is present on the class path, invoke the specified consumer {@code action} with the class object, + * otherwise do nothing. + * + * @param action block to be executed if a value is present. + */ + private static void ifClassPresent(String className, Consumer> action) { + if (ClassUtils.isPresent(className, PostgresDialect.class.getClassLoader())) { + action.accept(ClassUtils.resolveClassName(className, PostgresDialect.class.getClassLoader())); + } + } + static class JdbcPostgresArrayColumns implements JdbcArrayColumns { private static final boolean TYPE_INFO_PRESENT = ClassUtils.isPresent("org.postgresql.jdbc.TypeInfoCache", diff --git a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java index 2cfbfc359d..707395f14b 100644 --- a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java +++ b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/PostgresDialect.java @@ -2,18 +2,13 @@ import io.r2dbc.postgresql.codec.Json; -import java.net.InetAddress; -import java.net.URI; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.function.Consumer; import java.util.stream.Stream; @@ -51,7 +46,7 @@ public class PostgresDialect extends org.springframework.data.relational.core.di static { Set> simpleTypes = new HashSet<>( - Arrays.asList(UUID.class, URL.class, URI.class, InetAddress.class, Map.class)); + org.springframework.data.relational.core.dialect.PostgresDialect.INSTANCE.simpleTypes()); // conditional Postgres Geo support. Stream.of("io.r2dbc.postgresql.codec.Box", // diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java index eb06c91a70..2c8cdb03fc 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/PostgresDialect.java @@ -15,13 +15,15 @@ */ package org.springframework.data.relational.core.dialect; -import java.util.Arrays; +import java.net.InetAddress; +import java.net.URI; +import java.net.URL; +import java.rmi.server.UID; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.function.Consumer; import org.springframework.data.relational.core.sql.Functions; import org.springframework.data.relational.core.sql.IdentifierProcessing; @@ -32,7 +34,6 @@ import org.springframework.data.relational.core.sql.SimpleFunction; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.core.sql.TableLike; -import org.springframework.util.ClassUtils; /** * An SQL dialect for Postgres. @@ -50,6 +51,9 @@ public class PostgresDialect extends AbstractDialect { */ public static final PostgresDialect INSTANCE = new PostgresDialect(); + private static final Set> POSTGRES_SIMPLE_TYPES = Set.of(UID.class, URL.class, URI.class, InetAddress.class, + Map.class); + protected PostgresDialect() {} private static final LimitClause LIMIT_CLAUSE = new LimitClause() { @@ -152,32 +156,7 @@ public IdentifierProcessing getIdentifierProcessing() { @Override public Set> simpleTypes() { - - Set> simpleTypes = new HashSet<>(); - List simpleTypeNames = Arrays.asList( // - "org.postgresql.util.PGobject", // - "org.postgresql.geometric.PGpoint", // - "org.postgresql.geometric.PGbox", // - "org.postgresql.geometric.PGcircle", // - "org.postgresql.geometric.PGline", // - "org.postgresql.geometric.PGpath", // - "org.postgresql.geometric.PGpolygon", // - "org.postgresql.geometric.PGlseg" // - ); - simpleTypeNames.forEach(name -> ifClassPresent(name, simpleTypes::add)); - return Collections.unmodifiableSet(simpleTypes); - } - - /** - * If the class is present on the class path, invoke the specified consumer {@code action} with the class object, - * otherwise do nothing. - * - * @param action block to be executed if a value is present. - */ - private static void ifClassPresent(String className, Consumer> action) { - if (ClassUtils.isPresent(className, PostgresDialect.class.getClassLoader())) { - action.accept(ClassUtils.resolveClassName(className, PostgresDialect.class.getClassLoader())); - } + return POSTGRES_SIMPLE_TYPES; } @Override