From 272e0312732f1237596dde7fed82711fa3c5455e Mon Sep 17 00:00:00 2001 From: Manousos Mathioudakis Date: Wed, 10 Mar 2021 23:21:10 +0200 Subject: [PATCH 1/2] Map boolean values to 0 or 1 if dialect is SqlServerDialect. --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 +-- .../jdbc/repository/query/QueryMapper.java | 7 ++++ .../query/PartTreeJdbcQueryUnitTests.java | 33 +++++++++++++++++++ spring-data-relational/pom.xml | 4 +-- 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index b230bbb69e..286b7931b8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index a922ef00a2..73cbc32eee 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 6f04d6b4b0..ea96ea1cd9 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java index f8ee2d7b1e..5ed8cebe35 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java @@ -34,6 +34,7 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.Escaper; +import org.springframework.data.relational.core.dialect.SqlServerDialect; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.query.CriteriaDefinition; @@ -402,10 +403,16 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, i } if (comparator == Comparator.IS_TRUE) { + if (dialect instanceof SqlServerDialect) { + return column.isEqualTo(SQL.literalOf(1)); + } return column.isEqualTo(SQL.literalOf(true)); } if (comparator == Comparator.IS_FALSE) { + if (dialect instanceof SqlServerDialect) { + return column.isEqualTo(SQL.literalOf(0)); + } return column.isEqualTo(SQL.literalOf(false)); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java index 9adac223d8..ea567a4ce1 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQueryUnitTests.java @@ -38,6 +38,7 @@ import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.relational.core.dialect.H2Dialect; +import org.springframework.data.relational.core.dialect.SqlServerDialect; import org.springframework.data.relational.core.mapping.Embedded; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.Table; @@ -61,9 +62,14 @@ public class PartTreeJdbcQueryUnitTests { private static final String TABLE = "\"users\""; + private static final String TABLE_SQL_SERVER = "users"; private static final String ALL_FIELDS = "\"users\".\"ID\" AS \"ID\", \"users\".\"AGE\" AS \"AGE\", \"hated\".\"USER\" AS \"HATED_USER\", \"users\".\"ACTIVE\" AS \"ACTIVE\", \"users\".\"LAST_NAME\" AS \"LAST_NAME\", \"users\".\"FIRST_NAME\" AS \"FIRST_NAME\", \"users\".\"DATE_OF_BIRTH\" AS \"DATE_OF_BIRTH\", \"users\".\"HOBBY_REFERENCE\" AS \"HOBBY_REFERENCE\", \"hated\".\"NAME\" AS \"HATED_NAME\", \"users\".\"USER_CITY\" AS \"USER_CITY\", \"users\".\"USER_STREET\" AS \"USER_STREET\""; + private static final String ALL_FIELDS_SQL_SERVER = "users.id AS id, users.age AS age, hated.user AS hated_user, users.active AS active, users.last_name AS last_name, users.first_name AS first_name, users.date_of_birth AS date_of_birth, users.hobby_reference AS hobby_reference, hated.name AS hated_name, users.user_city AS user_city, users.user_street AS user_street"; private static final String JOIN_CLAUSE = "FROM \"users\" LEFT OUTER JOIN \"HOBBY\" \"hated\" ON \"hated\".\"USER\" = \"users\".\"ID\""; + private static final String JOIN_CLAUSE_SQL_SERVER = "FROM users LEFT OUTER JOIN hobby hated ON hated.user = users.id"; + private static final String BASE_SELECT = "SELECT " + ALL_FIELDS + " " + JOIN_CLAUSE; + private static final String BASE_SELECT_SQL_SERVER = "SELECT " + ALL_FIELDS_SQL_SERVER + " " + JOIN_CLAUSE_SQL_SERVER; JdbcMappingContext mappingContext = new JdbcMappingContext(); JdbcConverter converter = new BasicJdbcConverter(mappingContext, mock(RelationResolver.class)); @@ -441,6 +447,17 @@ public void createsQueryToFindAllEntitiesByBooleanAttributeTrue() throws Excepti assertThat(query.getQuery()).isEqualTo(BASE_SELECT + " WHERE " + TABLE + ".\"ACTIVE\" = TRUE"); } + @Test // issue-908 + public void createsQueryToFindAllEntitiesByBooleanAttributeTrueForSqlServer() throws Exception { + + JdbcQueryMethod queryMethod = getQueryMethod("findAllByActiveTrue"); + PartTreeJdbcQuery jdbcQuery = createQueryForSqlServer(queryMethod); + RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]); + ParametrizedQuery query = jdbcQuery.createQuery(accessor); + + assertThat(query.getQuery()).isEqualTo(BASE_SELECT_SQL_SERVER + " WHERE " + TABLE_SQL_SERVER + ".active = 1"); + } + @Test // DATAJDBC-318 public void createsQueryToFindAllEntitiesByBooleanAttributeFalse() throws Exception { @@ -452,6 +469,17 @@ public void createsQueryToFindAllEntitiesByBooleanAttributeFalse() throws Except assertThat(query.getQuery()).isEqualTo(BASE_SELECT + " WHERE " + TABLE + ".\"ACTIVE\" = FALSE"); } + @Test // issue-908 + public void createsQueryToFindAllEntitiesByBooleanAttributeFalseForSqlServer() throws Exception { + + JdbcQueryMethod queryMethod = getQueryMethod("findAllByActiveFalse"); + PartTreeJdbcQuery jdbcQuery = createQueryForSqlServer(queryMethod); + RelationalParametersParameterAccessor accessor = getAccessor(queryMethod, new Object[0]); + ParametrizedQuery query = jdbcQuery.createQuery(accessor); + + assertThat(query.getQuery()).isEqualTo(BASE_SELECT_SQL_SERVER + " WHERE " + TABLE_SQL_SERVER + ".active = 0"); + } + @Test // DATAJDBC-318 public void createsQueryToFindAllEntitiesByStringAttributeIgnoringCase() throws Exception { @@ -565,6 +593,11 @@ private PartTreeJdbcQuery createQuery(JdbcQueryMethod queryMethod) { mock(NamedParameterJdbcOperations.class), mock(RowMapper.class)); } + private PartTreeJdbcQuery createQueryForSqlServer(JdbcQueryMethod queryMethod) { + return new PartTreeJdbcQuery(mappingContext, queryMethod, SqlServerDialect.INSTANCE, converter, + mock(NamedParameterJdbcOperations.class), mock(RowMapper.class)); + } + private JdbcQueryMethod getQueryMethod(String methodName, Class... parameterTypes) throws Exception { Method method = UserRepository.class.getMethod(methodName, parameterTypes); return new JdbcQueryMethod(method, new DefaultRepositoryMetadata(UserRepository.class), diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 6b2507aabe..5681ef55e8 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.2.0-SNAPSHOT + 2.2.0-908-SNAPSHOT From 44a78f8261898ccf6fd04ef085ac12f9bf3b2877 Mon Sep 17 00:00:00 2001 From: Manousos Mathioudakis Date: Thu, 11 Mar 2021 17:23:11 +0200 Subject: [PATCH 2/2] Add booleanLiteral on Dialect. Implement booleanLiteral strategy for SqlServer dialect. Signed-off-by: Manousos Mathioudakis --- .../data/jdbc/repository/query/QueryMapper.java | 10 ++-------- .../data/relational/core/dialect/Dialect.java | 14 +++++++++++++- .../relational/core/dialect/SqlServerDialect.java | 7 +++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java index 5ed8cebe35..0547fef5bf 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/QueryMapper.java @@ -403,17 +403,11 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, i } if (comparator == Comparator.IS_TRUE) { - if (dialect instanceof SqlServerDialect) { - return column.isEqualTo(SQL.literalOf(1)); - } - return column.isEqualTo(SQL.literalOf(true)); + return column.isEqualTo(dialect.booleanLiteral(true)); } if (comparator == Comparator.IS_FALSE) { - if (dialect instanceof SqlServerDialect) { - return column.isEqualTo(SQL.literalOf(0)); - } - return column.isEqualTo(SQL.literalOf(false)); + return column.isEqualTo(dialect.booleanLiteral(false)); } Expression columnExpression = column; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java index 35097866d9..0785c83d07 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/Dialect.java @@ -16,6 +16,8 @@ package org.springframework.data.relational.core.dialect; import org.springframework.data.relational.core.sql.IdentifierProcessing; +import org.springframework.data.relational.core.sql.Literal; +import org.springframework.data.relational.core.sql.SQL; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.data.relational.core.sql.render.SelectRenderContext; @@ -84,5 +86,15 @@ default Escaper getLikeEscaper() { default IdGeneration getIdGeneration(){ return IdGeneration.DEFAULT; - }; + } + + /** + * Return the boolean literal based on dialect. + * + * @param value the boolean value + * @return the appropriate literal + */ + default Literal booleanLiteral(boolean value) { + return SQL.literalOf(value); + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java index c3b47653da..7f12434786 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SqlServerDialect.java @@ -16,7 +16,9 @@ package org.springframework.data.relational.core.dialect; import org.springframework.data.relational.core.sql.IdentifierProcessing; +import org.springframework.data.relational.core.sql.Literal; import org.springframework.data.relational.core.sql.LockOptions; +import org.springframework.data.relational.core.sql.SQL; import org.springframework.data.relational.core.sql.render.SelectRenderContext; import org.springframework.data.util.Lazy; @@ -150,4 +152,9 @@ public SelectRenderContext getSelectContext() { public IdentifierProcessing getIdentifierProcessing() { return IdentifierProcessing.NONE; } + + @Override + public Literal booleanLiteral(boolean value) { + return value ? SQL.literalOf(1) :SQL.literalOf(0); + } }