From 6f2cd3b8a24bb4e55042acc332c2161ac34a0e48 Mon Sep 17 00:00:00 2001 From: radovanradic Date: Tue, 10 Dec 2024 16:59:37 +0100 Subject: [PATCH 1/3] Fix QuerySpecification doesn't support selecting non-lowercase columns --- ...lumnNameExistenceAwareResultSetReader.java | 5 +++- .../data/jdbc/h2/H2RepositorySpec.groovy | 8 +++++ .../jdbc/mariadb/MariaRepositorySpec.groovy | 6 ++++ .../jdbc/mysql/MySqlRepositorySpec.groovy | 6 ++++ .../oraclexe/OracleXERepositorySpec.groovy | 6 ++++ .../postgres/PostgresRepositorySpec.groovy | 6 ++++ .../sqlserver/SqlServerRepositorySpec.groovy | 6 ++++ .../jdbc/h2/H2ExampleEntityRepository.java | 9 ++++++ .../mysql/MySqlExampleEntityRepository.java | 9 ++++++ .../OracleExampleEntityRepository.java | 9 ++++++ .../PostgresExampleEntityRepository.java | 9 ++++++ .../sqlserver/MSExampleEntityRepository.java | 9 ++++++ .../data/r2dbc/h2/H2RepositorySpec.groovy | 6 ++++ .../mariadb/MariaDbRepositorySpec.groovy | 6 ++++ .../r2dbc/mysql/MySqlRepositorySpec.groovy | 6 ++++ .../oraclexe/OracleXERepositorySpec.groovy | 6 ++++ .../postgres/PostgresRepositorySpec.groovy | 6 ++++ .../sqlserver/SqlServerRepositorySpec.groovy | 6 ++++ .../r2dbc/h2/H2ExampleEntityRepository.java | 9 ++++++ .../mysql/MySqlExampleEntityRepository.java | 9 ++++++ .../OracleExampleEntityRepository.java | 9 ++++++ .../PostgresExampleEntityRepository.java | 9 ++++++ .../sqlserver/MSExampleEntityRepository.java | 9 ++++++ .../tck/tests/AbstractRepositorySpec.groovy | 29 +++++++++++++++++++ .../data/tck/entities/ExampleEntity.java | 13 +++++++++ .../repositories/ExampleEntityRepository.java | 13 +++++++++ 26 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 data-jdbc/src/test/java/io/micronaut/data/jdbc/h2/H2ExampleEntityRepository.java create mode 100644 data-jdbc/src/test/java/io/micronaut/data/jdbc/mysql/MySqlExampleEntityRepository.java create mode 100644 data-jdbc/src/test/java/io/micronaut/data/jdbc/oraclexe/OracleExampleEntityRepository.java create mode 100644 data-jdbc/src/test/java/io/micronaut/data/jdbc/postgres/PostgresExampleEntityRepository.java create mode 100644 data-jdbc/src/test/java/io/micronaut/data/jdbc/sqlserver/MSExampleEntityRepository.java create mode 100644 data-r2dbc/src/test/java/io/micronaut/data/r2dbc/h2/H2ExampleEntityRepository.java create mode 100644 data-r2dbc/src/test/java/io/micronaut/data/r2dbc/mysql/MySqlExampleEntityRepository.java create mode 100644 data-r2dbc/src/test/java/io/micronaut/data/r2dbc/oraclexe/OracleExampleEntityRepository.java create mode 100644 data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java create mode 100644 data-r2dbc/src/test/java/io/micronaut/data/r2dbc/sqlserver/MSExampleEntityRepository.java create mode 100644 data-tck/src/main/java/io/micronaut/data/tck/entities/ExampleEntity.java create mode 100644 data-tck/src/main/java/io/micronaut/data/tck/repositories/ExampleEntityRepository.java diff --git a/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java b/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java index f5e1c87d55a..e8b77e904c5 100644 --- a/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java +++ b/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java @@ -49,6 +49,9 @@ public Object readDynamic(ResultSet resultSet, String index, DataType dataType) } private boolean containsColumnName(ResultSet resultSet, String name) { + if (name == null) { + return false; + } if (knownColumns == null) { try { ResultSetMetaData rsmd = resultSet.getMetaData(); @@ -61,6 +64,6 @@ private boolean containsColumnName(ResultSet resultSet, String name) { throw new RuntimeException(e); } } - return knownColumns.contains(name); + return knownColumns.contains(name.toLowerCase()); } } diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2RepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2RepositorySpec.groovy index 321920cf961..ffd91365258 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2RepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2RepositorySpec.groovy @@ -99,6 +99,9 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP @Shared H2BookEntityRepository bookEntityRepository = context.getBean(H2BookEntityRepository) + @Shared + H2ExampleEntityRepository exampleEntityRepo = context.getBean(H2ExampleEntityRepository) + @Override EntityWithIdClassRepository getEntityWithIdClassRepository() { return entityWithIdClassRepo @@ -221,6 +224,11 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP return pageRepo } + @Override + ExampleEntityRepository getExampleEntityRepository() { + return exampleEntityRepo + } + @Override boolean isSupportsArrays() { return true diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mariadb/MariaRepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mariadb/MariaRepositorySpec.groovy index aff08b06547..1266afa978b 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mariadb/MariaRepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mariadb/MariaRepositorySpec.groovy @@ -169,6 +169,12 @@ class MariaRepositorySpec extends AbstractRepositorySpec implements MariaTestPro return context.getBean(MySqlEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MySqlExampleEntityRepository) + } + @Override protected boolean skipCustomSchemaAndCatalogTest() { // INSERT command denied to user 'test'@'172.17.0.1' for table 'cars' diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mysql/MySqlRepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mysql/MySqlRepositorySpec.groovy index 5110f9a0202..c77a56975fd 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mysql/MySqlRepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/mysql/MySqlRepositorySpec.groovy @@ -167,6 +167,12 @@ class MySqlRepositorySpec extends AbstractRepositorySpec implements MySQLTestPro return context.getBean(MySqlEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MySqlExampleEntityRepository) + } + def "for update is in the correct location"() { given: setupBooks() diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/oraclexe/OracleXERepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/oraclexe/OracleXERepositorySpec.groovy index 0a352af516a..d6fd6d37c88 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/oraclexe/OracleXERepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/oraclexe/OracleXERepositorySpec.groovy @@ -172,6 +172,12 @@ class OracleXERepositorySpec extends AbstractRepositorySpec implements OracleTes return context.getBean(OracleXEEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(OracleExampleEntityRepository) + } + @Override protected boolean skipCustomSchemaAndCatalogTest() { // ORA-04043: object "FORD"."CARS" does not exist diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/postgres/PostgresRepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/postgres/PostgresRepositorySpec.groovy index 1dbf3640ccc..f56f898b346 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/postgres/PostgresRepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/postgres/PostgresRepositorySpec.groovy @@ -174,6 +174,12 @@ class PostgresRepositorySpec extends AbstractRepositorySpec implements PostgresT return context.getBean(PostgresEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(PostgresExampleEntityRepository) + } + @Memoized @Override boolean isSupportsArrays() { diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/sqlserver/SqlServerRepositorySpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/sqlserver/SqlServerRepositorySpec.groovy index d7daacc5233..d9375262756 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/sqlserver/SqlServerRepositorySpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/sqlserver/SqlServerRepositorySpec.groovy @@ -164,4 +164,10 @@ class SqlServerRepositorySpec extends AbstractRepositorySpec implements MSSQLTes EntityWithIdClass2Repository getEntityWithIdClass2Repository() { return context.getBean(MSEntityWithIdClass2Repository) } + + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MSExampleEntityRepository) + } } diff --git a/data-jdbc/src/test/java/io/micronaut/data/jdbc/h2/H2ExampleEntityRepository.java b/data-jdbc/src/test/java/io/micronaut/data/jdbc/h2/H2ExampleEntityRepository.java new file mode 100644 index 00000000000..7a56efb4226 --- /dev/null +++ b/data-jdbc/src/test/java/io/micronaut/data/jdbc/h2/H2ExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.jdbc.h2; + +import io.micronaut.data.jdbc.annotation.JdbcRepository; +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@JdbcRepository(dialect = Dialect.H2) +public interface H2ExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-jdbc/src/test/java/io/micronaut/data/jdbc/mysql/MySqlExampleEntityRepository.java b/data-jdbc/src/test/java/io/micronaut/data/jdbc/mysql/MySqlExampleEntityRepository.java new file mode 100644 index 00000000000..57b16ad0412 --- /dev/null +++ b/data-jdbc/src/test/java/io/micronaut/data/jdbc/mysql/MySqlExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.jdbc.mysql; + +import io.micronaut.data.jdbc.annotation.JdbcRepository; +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@JdbcRepository(dialect = Dialect.MYSQL) +public interface MySqlExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-jdbc/src/test/java/io/micronaut/data/jdbc/oraclexe/OracleExampleEntityRepository.java b/data-jdbc/src/test/java/io/micronaut/data/jdbc/oraclexe/OracleExampleEntityRepository.java new file mode 100644 index 00000000000..74c90ebaa8a --- /dev/null +++ b/data-jdbc/src/test/java/io/micronaut/data/jdbc/oraclexe/OracleExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.jdbc.oraclexe; + +import io.micronaut.data.jdbc.annotation.JdbcRepository; +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@JdbcRepository(dialect = Dialect.ORACLE) +public interface OracleExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-jdbc/src/test/java/io/micronaut/data/jdbc/postgres/PostgresExampleEntityRepository.java b/data-jdbc/src/test/java/io/micronaut/data/jdbc/postgres/PostgresExampleEntityRepository.java new file mode 100644 index 00000000000..ff29dd7b402 --- /dev/null +++ b/data-jdbc/src/test/java/io/micronaut/data/jdbc/postgres/PostgresExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.jdbc.postgres; + +import io.micronaut.data.jdbc.annotation.JdbcRepository; +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@JdbcRepository(dialect = Dialect.POSTGRES) +public interface PostgresExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-jdbc/src/test/java/io/micronaut/data/jdbc/sqlserver/MSExampleEntityRepository.java b/data-jdbc/src/test/java/io/micronaut/data/jdbc/sqlserver/MSExampleEntityRepository.java new file mode 100644 index 00000000000..e776bf5ea6d --- /dev/null +++ b/data-jdbc/src/test/java/io/micronaut/data/jdbc/sqlserver/MSExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.jdbc.sqlserver; + +import io.micronaut.data.jdbc.annotation.JdbcRepository; +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@JdbcRepository(dialect = Dialect.SQL_SERVER) +public interface MSExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/h2/H2RepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/h2/H2RepositorySpec.groovy index 1eaf4806a4d..2fccdef4993 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/h2/H2RepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/h2/H2RepositorySpec.groovy @@ -164,6 +164,12 @@ class H2RepositorySpec extends AbstractRepositorySpec implements H2TestPropertyP return context.getBean(H2EntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(H2ExampleEntityRepository) + } + @Override protected boolean skipQueryByDataArray() { return true diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mariadb/MariaDbRepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mariadb/MariaDbRepositorySpec.groovy index d567d0b6a42..290d1eb7bf1 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mariadb/MariaDbRepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mariadb/MariaDbRepositorySpec.groovy @@ -166,6 +166,12 @@ class MariaDbRepositorySpec extends AbstractRepositorySpec implements MariaDbTes return context.getBean(MySqlPageRepository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MySqlExampleEntityRepository) + } + @Override protected boolean skipCustomSchemaAndCatalogTest() { // INSERT command denied to user 'test'@'172.17.0.1' for table 'cars' diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mysql/MySqlRepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mysql/MySqlRepositorySpec.groovy index c34d002b471..31239a11716 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mysql/MySqlRepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/mysql/MySqlRepositorySpec.groovy @@ -170,6 +170,12 @@ class MySqlRepositorySpec extends AbstractRepositorySpec implements MySqlTestPro return context.getBean(MySqlEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MySqlExampleEntityRepository) + } + @Override protected boolean skipCustomSchemaAndCatalogTest() { // INSERT command denied to user 'test'@'172.17.0.1' for table 'cars' diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/oraclexe/OracleXERepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/oraclexe/OracleXERepositorySpec.groovy index 763594d80ab..c526bc01dab 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/oraclexe/OracleXERepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/oraclexe/OracleXERepositorySpec.groovy @@ -170,6 +170,12 @@ class OracleXERepositorySpec extends AbstractRepositorySpec implements OracleXET return context.getBean(OracleXEEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(OracleExampleEntityRepository) + } + @Override protected boolean skipCustomSchemaAndCatalogTest() { // ORA-04043: object "FORD"."CARS" does not exist diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/postgres/PostgresRepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/postgres/PostgresRepositorySpec.groovy index 8d918300b0e..d293a3fe197 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/postgres/PostgresRepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/postgres/PostgresRepositorySpec.groovy @@ -165,6 +165,12 @@ class PostgresRepositorySpec extends AbstractRepositorySpec implements PostgresT return context.getBean(PostgresEntityWithIdClass2Repository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(PostgresExampleEntityRepository) + } + @Override boolean isSupportsArrays() { return true diff --git a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/sqlserver/SqlServerRepositorySpec.groovy b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/sqlserver/SqlServerRepositorySpec.groovy index 993cc6526f1..b2e1d775e9e 100644 --- a/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/sqlserver/SqlServerRepositorySpec.groovy +++ b/data-r2dbc/src/test/groovy/io/micronaut/data/r2dbc/sqlserver/SqlServerRepositorySpec.groovy @@ -170,6 +170,12 @@ class SqlServerRepositorySpec extends AbstractRepositorySpec implements SqlServe return context.getBean(MSPageRepository) } + @Memoized + @Override + ExampleEntityRepository getExampleEntityRepository() { + return context.getBean(MSExampleEntityRepository) + } + @Override boolean supportsNullCharacter() { false diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/h2/H2ExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/h2/H2ExampleEntityRepository.java new file mode 100644 index 00000000000..74c1ef38fb1 --- /dev/null +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/h2/H2ExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.r2dbc.h2; + +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.r2dbc.annotation.R2dbcRepository; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@R2dbcRepository(dialect = Dialect.H2) +public interface H2ExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/mysql/MySqlExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/mysql/MySqlExampleEntityRepository.java new file mode 100644 index 00000000000..3f6434e56be --- /dev/null +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/mysql/MySqlExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.r2dbc.mysql; + +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.r2dbc.annotation.R2dbcRepository; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@R2dbcRepository(dialect = Dialect.MYSQL) +public interface MySqlExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/oraclexe/OracleExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/oraclexe/OracleExampleEntityRepository.java new file mode 100644 index 00000000000..f644dede2af --- /dev/null +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/oraclexe/OracleExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.r2dbc.oraclexe; + +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.r2dbc.annotation.R2dbcRepository; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@R2dbcRepository(dialect = Dialect.ORACLE) +public interface OracleExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java new file mode 100644 index 00000000000..06cef8a9316 --- /dev/null +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.r2dbc.postgres; + +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.r2dbc.annotation.R2dbcRepository; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@R2dbcRepository(dialect = Dialect.H2) +public interface PostgresExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/sqlserver/MSExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/sqlserver/MSExampleEntityRepository.java new file mode 100644 index 00000000000..ad69b67c9b9 --- /dev/null +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/sqlserver/MSExampleEntityRepository.java @@ -0,0 +1,9 @@ +package io.micronaut.data.r2dbc.sqlserver; + +import io.micronaut.data.model.query.builder.sql.Dialect; +import io.micronaut.data.r2dbc.annotation.R2dbcRepository; +import io.micronaut.data.tck.repositories.ExampleEntityRepository; + +@R2dbcRepository(dialect = Dialect.SQL_SERVER) +public interface MSExampleEntityRepository extends ExampleEntityRepository { +} diff --git a/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy b/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy index c55a31ea82e..36f73c507ff 100644 --- a/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy +++ b/data-tck/src/main/groovy/io/micronaut/data/tck/tests/AbstractRepositorySpec.groovy @@ -45,6 +45,7 @@ import io.micronaut.data.tck.entities.CountryRegionCity import io.micronaut.data.tck.entities.EntityIdClass import io.micronaut.data.tck.entities.EntityWithIdClass import io.micronaut.data.tck.entities.EntityWithIdClass2 +import io.micronaut.data.tck.entities.ExampleEntity import io.micronaut.data.tck.entities.Face import io.micronaut.data.tck.entities.Food import io.micronaut.data.tck.entities.Genre @@ -120,6 +121,7 @@ abstract class AbstractRepositorySpec extends Specification { abstract PageRepository getPageRepository() abstract EntityWithIdClassRepository getEntityWithIdClassRepository() abstract EntityWithIdClass2Repository getEntityWithIdClass2Repository() + abstract ExampleEntityRepository getExampleEntityRepository() abstract Map getProperties() @@ -3416,6 +3418,33 @@ abstract class AbstractRepositorySpec extends Specification { books.size() > 0 } + void "test query specification with uppercase/lowercase column names"() { + given: + exampleEntityRepository.save(new ExampleEntity(1, "foo", "bar")) + when: + QuerySpecification qs = (root, query, criteriaBuilder) -> { + query.multiselect( + root.get("id"), + root.get("lowercaseColumn")) + return criteriaBuilder.equal(root.get("id"), 1) + } + def entity = exampleEntityRepository.find(qs) + then: + entity.lowercaseColumn() == "bar" + when: + qs = (root, query, criteriaBuilder) -> { + query.multiselect( + root.get("id"), + root.get("uppercaseColumn")) + return criteriaBuilder.equal(root.get("id"), 1) + } + entity = exampleEntityRepository.find(qs) + then: + entity.uppercaseColumn() == "foo" + cleanup: + exampleEntityRepository.deleteById(1) + } + private GregorianCalendar getYearMonthDay(Date dateCreated) { def cal = dateCreated.toCalendar() def localDate = LocalDate.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH)) diff --git a/data-tck/src/main/java/io/micronaut/data/tck/entities/ExampleEntity.java b/data-tck/src/main/java/io/micronaut/data/tck/entities/ExampleEntity.java new file mode 100644 index 00000000000..1f6da13e600 --- /dev/null +++ b/data-tck/src/main/java/io/micronaut/data/tck/entities/ExampleEntity.java @@ -0,0 +1,13 @@ +package io.micronaut.data.tck.entities; + +import io.micronaut.core.annotation.Nullable; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public record ExampleEntity( + @Id Integer id, + @Nullable @Column(name = "UPPERCASE_COLUMN") String uppercaseColumn, + @Nullable @Column(name = "lowercase_column") String lowercaseColumn) { +} diff --git a/data-tck/src/main/java/io/micronaut/data/tck/repositories/ExampleEntityRepository.java b/data-tck/src/main/java/io/micronaut/data/tck/repositories/ExampleEntityRepository.java new file mode 100644 index 00000000000..243d50cc414 --- /dev/null +++ b/data-tck/src/main/java/io/micronaut/data/tck/repositories/ExampleEntityRepository.java @@ -0,0 +1,13 @@ +package io.micronaut.data.tck.repositories; + +import io.micronaut.data.repository.GenericRepository; +import io.micronaut.data.repository.jpa.criteria.QuerySpecification; +import io.micronaut.data.tck.entities.ExampleEntity; + +public interface ExampleEntityRepository extends GenericRepository { + void save(ExampleEntity entity); + + ExampleEntity find(QuerySpecification querySpecification); + + void deleteById(Integer id); +} From 49c17a97f36b19a08ec1cee744476a1eb3c5f574 Mon Sep 17 00:00:00 2001 From: radovanradic Date: Tue, 10 Dec 2024 18:00:03 +0100 Subject: [PATCH 2/3] Fixed postgres repository dialect --- .../data/r2dbc/postgres/PostgresExampleEntityRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java index 06cef8a9316..c9aa4ed7757 100644 --- a/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java +++ b/data-r2dbc/src/test/java/io/micronaut/data/r2dbc/postgres/PostgresExampleEntityRepository.java @@ -4,6 +4,6 @@ import io.micronaut.data.r2dbc.annotation.R2dbcRepository; import io.micronaut.data.tck.repositories.ExampleEntityRepository; -@R2dbcRepository(dialect = Dialect.H2) +@R2dbcRepository(dialect = Dialect.POSTGRES) public interface PostgresExampleEntityRepository extends ExampleEntityRepository { } From af66832b9e3a666e327e54f68861fc521dd45efc Mon Sep 17 00:00:00 2001 From: radovanradic Date: Tue, 10 Dec 2024 19:06:24 +0100 Subject: [PATCH 3/3] Try to make Sonar happier --- .../ColumnNameExistenceAwareResultSetReader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java b/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java index e8b77e904c5..6ee76d45e0a 100644 --- a/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java +++ b/data-jdbc/src/main/java/io/micronaut/data/jdbc/mapper/ColumnNameExistenceAwareResultSetReader.java @@ -49,21 +49,22 @@ public Object readDynamic(ResultSet resultSet, String index, DataType dataType) } private boolean containsColumnName(ResultSet resultSet, String name) { - if (name == null) { - return false; - } if (knownColumns == null) { try { ResultSetMetaData rsmd = resultSet.getMetaData(); int columnsCount = rsmd.getColumnCount(); knownColumns = CollectionUtils.newHashSet(columnsCount); for (int x = 1; x <= columnsCount; x++) { - knownColumns.add(rsmd.getColumnLabel(x).toLowerCase()); + knownColumns.add(toLowerCase(rsmd.getColumnLabel(x))); } } catch (SQLException e) { throw new RuntimeException(e); } } - return knownColumns.contains(name.toLowerCase()); + return knownColumns.contains(toLowerCase(name)); + } + + private static String toLowerCase(String str) { + return str == null ? null : str.toLowerCase(); } }