diff --git a/pom.xml b/pom.xml index eeaa0b9e93..aa38ad037b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 2.3.0-SNAPSHOT + 2.3.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 03d6a5c2a0..3d1a946dcd 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.3.0-SNAPSHOT + 2.3.0-908-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index d7722eca4e..61371a9883 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 2.3.0-SNAPSHOT + 2.3.0-908-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 2.3.0-SNAPSHOT + 2.3.0-908-SNAPSHOT @@ -263,6 +263,12 @@ ${jmolecules-integration} test + + javax.annotation + jsr250-api + 1.0 + test + 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..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 @@ -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,11 +403,11 @@ private Condition createCondition(Column column, @Nullable Object mappedValue, i } if (comparator == Comparator.IS_TRUE) { - return column.isEqualTo(SQL.literalOf(true)); + return column.isEqualTo(dialect.booleanLiteral(true)); } if (comparator == Comparator.IS_FALSE) { - return column.isEqualTo(SQL.literalOf(false)); + return column.isEqualTo(dialect.booleanLiteral(false)); } Expression columnExpression = column; 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 4e42a006ec..e73240a998 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 2.3.0-SNAPSHOT + 2.3.0-908-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 2.3.0-SNAPSHOT + 2.3.0-908-SNAPSHOT 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); + } }