diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContext.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContext.java index 570d4a8f92..8871cd9f3e 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContext.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContext.java @@ -44,6 +44,7 @@ * * @author Jens Schauder * @author Greg Turnquist + * @author Kazuki Shimizu * @since 2.0 */ public class JdbcMappingContext extends AbstractMappingContext, JdbcPersistentProperty> { @@ -56,6 +57,7 @@ public class JdbcMappingContext extends AbstractMappingContext {}); } + @Override + public void setSimpleTypeHolder(SimpleTypeHolder simpleTypes) { + super.setSimpleTypeHolder(simpleTypes); + this.simpleTypeHolder = simpleTypes; + } + public List referencedEntities(Class rootType, PropertyPath path) { List paths = new ArrayList<>(); diff --git a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java index ec097d6a9f..be2d0667e4 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java +++ b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java @@ -17,6 +17,7 @@ import java.lang.reflect.Method; +import org.springframework.core.convert.ConversionService; import org.springframework.data.jdbc.core.DataAccessStrategy; import org.springframework.data.jdbc.core.EntityRowMapper; import org.springframework.data.jdbc.mapping.model.JdbcMappingContext; @@ -27,22 +28,26 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.SingleColumnRowMapper; /** * {@link QueryLookupStrategy} for JDBC repositories. Currently only supports annotated queries. * * @author Jens Schauder + * @author Kazuki Shimizu */ class JdbcQueryLookupStrategy implements QueryLookupStrategy { private final JdbcMappingContext context; private final DataAccessStrategy accessStrategy; + private final ConversionService conversionService; JdbcQueryLookupStrategy(EvaluationContextProvider evaluationContextProvider, JdbcMappingContext context, DataAccessStrategy accessStrategy) { this.context = context; this.accessStrategy = accessStrategy; + this.conversionService = context.getConversions(); } @Override @@ -50,10 +55,12 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repository ProjectionFactory projectionFactory, NamedQueries namedQueries) { JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory); - Class domainType = queryMethod.getReturnedObjectType(); - RowMapper rowMapper = new EntityRowMapper<>(context.getRequiredPersistentEntity(domainType), - context.getConversions(), context, accessStrategy); - + Class returnedObjectType = queryMethod.getReturnedObjectType(); + RowMapper rowMapper = context.getSimpleTypeHolder().isSimpleType(returnedObjectType) + ? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService) + : new EntityRowMapper<>(context.getRequiredPersistentEntity(returnedObjectType), conversionService, + context, accessStrategy); return new JdbcRepositoryQuery(queryMethod, context, rowMapper); } + } diff --git a/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java index 243e7c9119..ff216f6dd0 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java @@ -33,6 +33,8 @@ import org.springframework.test.context.junit4.rules.SpringMethodRule; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -165,6 +167,48 @@ public void executeCustomQueryWithReturnTypeIsStream() { .containsExactlyInAnyOrder("a", "b"); } + + @Test // DATAJDBC-175 + public void executeCustomQueryWithReturnTypeIsNubmer() { + + repository.save(dummyEntity("aaa")); + repository.save(dummyEntity("bbb")); + repository.save(dummyEntity("cac")); + + int count = repository.countByNameContaining("a"); + + assertThat(count).isEqualTo(2); + + } + + @Test // DATAJDBC-175 + public void executeCustomQueryWithReturnTypeIsBoolean() { + + repository.save(dummyEntity("aaa")); + repository.save(dummyEntity("bbb")); + repository.save(dummyEntity("cac")); + + assertThat(repository.existsByNameContaining("a")).isTrue(); + assertThat(repository.existsByNameContaining("d")).isFalse(); + + } + + @Test // DATAJDBC-175 + public void executeCustomQueryWithReturnTypeIsDate() { + + Date now = new Date(); + assertThat(repository.nowWithDate()).isAfterOrEqualsTo(now); + + } + + @Test // DATAJDBC-175 + public void executeCustomQueryWithReturnTypeIsLocalDateTimeList() { + + LocalDateTime now = LocalDateTime.now(); + repository.nowWithLocalDateTimeList() // + .forEach(d -> assertThat(d).isAfterOrEqualTo(now)); + + } private DummyEntity dummyEntity(String name) { @@ -209,5 +253,17 @@ private interface DummyEntityRepository extends CrudRepository findAllWithReturnTypeIsStream(); + @Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'") + int countByNameContaining(@Param("name") String name); + + @Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'") + boolean existsByNameContaining(@Param("name") String name); + + @Query("VALUES (current_timestamp)") + Date nowWithDate(); + + @Query("VALUES (current_timestamp),(current_timestamp)") + List nowWithLocalDateTimeList(); + } }