From bc0d307415c0a00a358dcba48edca4a5c504af0a Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 27 Aug 2021 09:29:49 +0200 Subject: [PATCH] SQL type used in array construction depends on Dialect. Postgres requires the non standard type "FLOAT8" for "DOUBLE". This is accomplished by making the conversion dependent on the dialect. This required a new JdbcDialect interface in order to keep the JDBC annotation out of the relational module. Closes #1033 Original pull request: #1037. --- .../core/convert/DefaultJdbcTypeFactory.java | 15 ++++- .../jdbc/core/dialect/JdbcArrayColumns.java | 60 +++++++++++++++++++ .../data/jdbc/core/dialect/JdbcDialect.java | 37 ++++++++++++ .../core/dialect/JdbcPostgresDialect.java | 44 ++++++++++++++ .../config/AbstractJdbcConfiguration.java | 17 ++++-- .../repository/config/DialectResolver.java | 10 +--- ...JdbcAggregateTemplateIntegrationTests.java | 26 +++++++- .../data/jdbc/testing/TestConfiguration.java | 9 ++- ...bcAggregateTemplateIntegrationTests-h2.sql | 6 ++ ...AggregateTemplateIntegrationTests-hsql.sql | 6 ++ ...egateTemplateIntegrationTests-postgres.sql | 6 ++ .../core/dialect/PostgresDialect.java | 3 +- 12 files changed, 222 insertions(+), 17 deletions(-) create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcArrayColumns.java create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java index 960997c6a..18f9df232 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java @@ -17,6 +17,7 @@ package org.springframework.data.jdbc.core.convert; import java.sql.Array; import java.sql.JDBCType; +import java.util.function.Function; import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.jdbc.core.ConnectionCallback; @@ -33,6 +34,7 @@ import org.springframework.util.Assert; public class DefaultJdbcTypeFactory implements JdbcTypeFactory { private final JdbcOperations operations; + private final Function jdbcTypeToSqlName; /** * Creates a new {@link DefaultJdbcTypeFactory}. @@ -40,10 +42,21 @@ public class DefaultJdbcTypeFactory implements JdbcTypeFactory { * @param operations must not be {@literal null}. */ public DefaultJdbcTypeFactory(JdbcOperations operations) { + this(operations, JDBCType::getName); + } + + /** + * Creates a new {@link DefaultJdbcTypeFactory}. + * + * @param operations must not be {@literal null}. + */ + public DefaultJdbcTypeFactory(JdbcOperations operations, Function jdbcTypeToSqlName) { Assert.notNull(operations, "JdbcOperations must not be null"); + Assert.notNull(jdbcTypeToSqlName, "JdbcTypeToSqlName must not be null"); this.operations = operations; + this.jdbcTypeToSqlName = jdbcTypeToSqlName; } @Override @@ -55,7 +68,7 @@ public class DefaultJdbcTypeFactory implements JdbcTypeFactory { JDBCType jdbcType = JdbcUtil.jdbcTypeFor(componentType); Assert.notNull(jdbcType, () -> String.format("Couldn't determine JDBCType for %s", componentType)); - String typeName = jdbcType.getName(); + String typeName = jdbcTypeToSqlName.apply(jdbcType); return operations.execute((ConnectionCallback) c -> c.createArrayOf(typeName, value)); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcArrayColumns.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcArrayColumns.java new file mode 100644 index 000000000..3c90c194b --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcArrayColumns.java @@ -0,0 +1,60 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.core.dialect; + +import java.sql.JDBCType; + +import org.springframework.data.relational.core.dialect.ArrayColumns; + +/** + * {@link org.springframework.data.relational.core.dialect.ArrayColumns} that offer JDBC specific functionality. + * + * @author Jens Schauder + * @since 2.3 + */ +public interface JdbcArrayColumns extends ArrayColumns { + + JdbcArrayColumns UNSUPPORTED = new JdbcArrayColumns() { + @Override + public boolean isSupported() { + return false; + } + + @Override + public Class getArrayType(Class userType) { + throw new UnsupportedOperationException("Array types not supported"); + } + + @Override + public String getSqlTypeRepresentation(JDBCType jdbcType) { + throw new UnsupportedOperationException("Array types not supported"); + } + }; + + /** + * The appropriate SQL type as a String which should be used to represent the given {@link JDBCType} in an + * {@link java.sql.Array}. Defaults to the name of the argument. + * + * @param jdbcType the {@link JDBCType} value representing the type that should be stored in the + * {@link java.sql.Array}. Must not be {@literal null}. + * @return the appropriate SQL type as a String which should be used to represent the given {@link JDBCType} in an + * {@link java.sql.Array}. Guaranteed to be not {@literal null}. + */ + default String getSqlTypeRepresentation(JDBCType jdbcType) { + return jdbcType.getName(); + } + +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java new file mode 100644 index 000000000..0dc94d9aa --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.core.dialect; + +import org.springframework.data.relational.core.dialect.Dialect; + +/** + * {@link org.springframework.data.relational.core.dialect.ArrayColumns} that offer JDBC specific functionality. + * + * @author Jens Schauder + * @since 2.3 + */ +public interface JdbcDialect extends Dialect { + + /** + * Returns the JDBC specific array support object that describes how array-typed columns are supported by this + * dialect. + * + * @return the JDBC specific array support object that describes how array-typed columns are supported by this + * dialect. + */ + @Override + JdbcArrayColumns getArraySupport(); +} 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 new file mode 100644 index 000000000..839f8ff79 --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc.core.dialect; + +import java.sql.JDBCType; + +import org.springframework.data.relational.core.dialect.PostgresDialect; + +/** + * JDBC specific Postgres Dialect. + * + * @author Jens Schauder + * @since 2.3 + */ +public class JdbcPostgresDialect extends PostgresDialect implements JdbcDialect { + + public static final JdbcPostgresDialect INSTANCE = new JdbcPostgresDialect(); + private static final JdbcPostgresArrayColumns ARRAY_COLUMNS = new JdbcPostgresArrayColumns(); + + @Override + public JdbcArrayColumns getArraySupport() { + return ARRAY_COLUMNS; + } + + static class JdbcPostgresArrayColumns extends PostgresArrayColumns implements JdbcArrayColumns { + @Override + public String getSqlTypeRepresentation(JDBCType jdbcType) { + return jdbcType == JDBCType.DOUBLE ? "FLOAT8" : jdbcType.getName(); + } + } +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java index 7aca5b75f..9f239e2fb 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java @@ -15,10 +15,12 @@ */ package org.springframework.data.jdbc.repository.config; +import java.sql.JDBCType; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,7 +33,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.CustomConversions; -import org.springframework.data.convert.CustomConversions.StoreConversions; import org.springframework.data.jdbc.core.JdbcAggregateOperations; import org.springframework.data.jdbc.core.JdbcAggregateTemplate; import org.springframework.data.jdbc.core.convert.BasicJdbcConverter; @@ -42,12 +43,11 @@ import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; import org.springframework.data.jdbc.core.convert.RelationResolver; import org.springframework.data.jdbc.core.convert.SqlGeneratorSource; -import org.springframework.data.jdbc.core.dialect.JdbcDb2Dialect; +import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.relational.core.conversion.RelationalConverter; -import org.springframework.data.relational.core.dialect.Db2Dialect; import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.mapping.NamingStrategy; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; @@ -66,7 +66,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; @Configuration(proxyBeanMethods = false) public class AbstractJdbcConfiguration implements ApplicationContextAware { - private static Logger LOG = LoggerFactory.getLogger(AbstractJdbcConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractJdbcConfiguration.class); private ApplicationContext applicationContext; @@ -100,7 +100,11 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware { public JdbcConverter jdbcConverter(JdbcMappingContext mappingContext, NamedParameterJdbcOperations operations, @Lazy RelationResolver relationResolver, JdbcCustomConversions conversions, Dialect dialect) { - DefaultJdbcTypeFactory jdbcTypeFactory = new DefaultJdbcTypeFactory(operations.getJdbcOperations()); + Function jdbcTypeToSqlName = dialect instanceof JdbcDialect + ? ((JdbcDialect) dialect).getArraySupport()::getSqlTypeRepresentation + : JDBCType::getName; + DefaultJdbcTypeFactory jdbcTypeFactory = new DefaultJdbcTypeFactory(operations.getJdbcOperations(), + jdbcTypeToSqlName); return new BasicJdbcConverter(mappingContext, relationResolver, conversions, jdbcTypeFactory, dialect.getIdentifierProcessing()); @@ -120,7 +124,8 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware { try { Dialect dialect = applicationContext.getBean(Dialect.class); - SimpleTypeHolder simpleTypeHolder = dialect.simpleTypes().isEmpty() ? JdbcSimpleTypes.HOLDER : new SimpleTypeHolder(dialect.simpleTypes(), JdbcSimpleTypes.HOLDER); + SimpleTypeHolder simpleTypeHolder = dialect.simpleTypes().isEmpty() ? JdbcSimpleTypes.HOLDER + : new SimpleTypeHolder(dialect.simpleTypes(), JdbcSimpleTypes.HOLDER); return new JdbcCustomConversions( CustomConversions.StoreConversions.of(simpleTypeHolder, storeConverters(dialect)), userConverters()); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java index d7f49fd65..2f7b36702 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java @@ -31,16 +31,12 @@ import org.springframework.dao.NonTransientDataAccessException; import org.springframework.data.jdbc.core.dialect.JdbcDb2Dialect; import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect; import org.springframework.data.jdbc.core.dialect.JdbcMySqlDialect; +import org.springframework.data.jdbc.core.dialect.JdbcPostgresDialect; import org.springframework.data.jdbc.core.dialect.JdbcSqlServerDialect; -import org.springframework.data.relational.core.dialect.Db2Dialect; import org.springframework.data.relational.core.dialect.Dialect; -import org.springframework.data.relational.core.dialect.H2Dialect; import org.springframework.data.relational.core.dialect.HsqlDbDialect; import org.springframework.data.relational.core.dialect.MariaDbDialect; -import org.springframework.data.relational.core.dialect.MySqlDialect; import org.springframework.data.relational.core.dialect.OracleDialect; -import org.springframework.data.relational.core.dialect.PostgresDialect; -import org.springframework.data.relational.core.dialect.SqlServerDialect; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.util.Optionals; import org.springframework.jdbc.core.ConnectionCallback; @@ -132,7 +128,7 @@ public class DialectResolver { return new MariaDbDialect(getIdentifierProcessing(metaData)); } if (name.contains("postgresql")) { - return PostgresDialect.INSTANCE; + return JdbcPostgresDialect.INSTANCE; } if (name.contains("microsoft")) { return JdbcSqlServerDialect.INSTANCE; @@ -144,7 +140,7 @@ public class DialectResolver { return OracleDialect.INSTANCE; } - LOG.info(String.format("Couldn't determine Dialect for \"%s\"", name) ); + LOG.info(String.format("Couldn't determine Dialect for \"%s\"", name)); return null; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 371c47b92..334dca890 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -555,6 +555,24 @@ public class JdbcAggregateTemplateIntegrationTests { assertThat(reloaded.digits).isEqualTo(Arrays.asList("one", "two", "three")); } + @Test // GH-1033 + @EnabledOnFeature(SUPPORTS_ARRAYS) + public void saveAndLoadAnEntityWithListOfDouble() { + + DoubleListOwner doubleListOwner = new DoubleListOwner(); + doubleListOwner.digits.addAll(Arrays.asList(1.2, 1.3, 1.4)); + + DoubleListOwner saved = template.save(doubleListOwner); + + assertThat(saved.id).isNotNull(); + + DoubleListOwner reloaded = template.findById(saved.id, DoubleListOwner.class); + + assertThat(reloaded).isNotNull(); + assertThat(reloaded.id).isEqualTo(saved.id); + assertThat(reloaded.digits).isEqualTo(Arrays.asList(1.2, 1.3, 1.4)); + } + @Test // DATAJDBC-259 @EnabledOnFeature(SUPPORTS_ARRAYS) public void saveAndLoadAnEntityWithSet() { @@ -911,7 +929,6 @@ public class JdbcAggregateTemplateIntegrationTests { List digits = new ArrayList<>(); } - @Table("ARRAY_OWNER") private static class SetOwner { @Id Long id; @@ -919,6 +936,13 @@ public class JdbcAggregateTemplateIntegrationTests { Set digits = new HashSet<>(); } + private static class DoubleListOwner { + + @Id Long id; + + List digits = new ArrayList<>(); + } + @Data static class LegoSet { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java index e74d30b0b..77f79f42f 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java @@ -15,10 +15,12 @@ */ package org.springframework.data.jdbc.testing; +import java.sql.JDBCType; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.sql.DataSource; @@ -40,6 +42,7 @@ import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; import org.springframework.data.jdbc.core.convert.RelationResolver; import org.springframework.data.jdbc.core.convert.SqlGeneratorSource; +import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes; import org.springframework.data.jdbc.repository.config.DialectResolver; @@ -136,11 +139,15 @@ public class TestConfiguration { CustomConversions conversions, @Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, Dialect dialect) { + Function jdbcTypeToSqlName = dialect instanceof JdbcDialect + ? ((JdbcDialect) dialect).getArraySupport()::getSqlTypeRepresentation + : JDBCType::getName; + return new BasicJdbcConverter( // mappingContext, // relationResolver, // conversions, // - new DefaultJdbcTypeFactory(template.getJdbcOperations()), // + new DefaultJdbcTypeFactory(template.getJdbcOperations(), jdbcTypeToSqlName), // dialect.getIdentifierProcessing()); } diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql index 63294ab7d..8add25c8e 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql @@ -52,6 +52,12 @@ CREATE TABLE BYTE_ARRAY_OWNER BINARY_DATA BYTEA NOT NULL ); +CREATE TABLE DOUBLE_LIST_OWNER +( + ID SERIAL PRIMARY KEY, + DIGITS ARRAY[10] +); + CREATE TABLE CHAIN4 ( FOUR SERIAL PRIMARY KEY, diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql index fda435ea4..96c5145e2 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql @@ -54,6 +54,12 @@ CREATE TABLE BYTE_ARRAY_OWNER BINARY_DATA VARBINARY(20) NOT NULL ); +CREATE TABLE DOUBLE_LIST_OWNER +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, + DIGITS DOUBLE PRECISION ARRAY[10] +); + CREATE TABLE CHAIN4 ( FOUR BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 40) PRIMARY KEY, diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql index 47c6841e6..e1990584a 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql @@ -61,6 +61,12 @@ CREATE TABLE "ARRAY_OWNER" MULTIDIMENSIONAL VARCHAR(20)[10][10] ); +CREATE TABLE DOUBLE_LIST_OWNER +( + ID SERIAL PRIMARY KEY, + DIGITS DOUBLE PRECISION[10] +); + CREATE TABLE BYTE_ARRAY_OWNER ( ID SERIAL PRIMARY KEY, 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 9495c2cd3..e43855826 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,6 +15,7 @@ */ package org.springframework.data.relational.core.dialect; +import java.sql.JDBCType; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -178,7 +179,7 @@ public class PostgresDialect extends AbstractDialect { } } - static class PostgresArrayColumns implements ArrayColumns { + protected static class PostgresArrayColumns implements ArrayColumns { /* * (non-Javadoc)