Skip to content

Commit 369ca6d

Browse files
kazuki43zooschauder
authored andcommitted
DATAJDBC-175 - Supports simple types as return type for annotated methods.
Original pull request: #43.
1 parent 4cb50ca commit 369ca6d

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

src/main/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContext.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
*
4545
* @author Jens Schauder
4646
* @author Greg Turnquist
47+
* @author Kazuki Shimizu
4748
* @since 2.0
4849
*/
4950
public class JdbcMappingContext extends AbstractMappingContext<JdbcPersistentEntity<?>, JdbcPersistentProperty> {
@@ -56,6 +57,7 @@ public class JdbcMappingContext extends AbstractMappingContext<JdbcPersistentEnt
5657

5758
@Getter private final NamingStrategy namingStrategy;
5859
@Getter private final NamedParameterJdbcOperations template;
60+
@Getter private SimpleTypeHolder simpleTypeHolder;
5961
private GenericConversionService conversions = getDefaultConversionService();
6062

6163
public JdbcMappingContext(NamingStrategy namingStrategy, NamedParameterJdbcOperations template,
@@ -72,6 +74,12 @@ public JdbcMappingContext(NamedParameterJdbcOperations template) {
7274
this(new DefaultNamingStrategy(), template, __ -> {});
7375
}
7476

77+
@Override
78+
public void setSimpleTypeHolder(SimpleTypeHolder simpleTypes) {
79+
super.setSimpleTypeHolder(simpleTypes);
80+
this.simpleTypeHolder = simpleTypes;
81+
}
82+
7583
public List<PropertyPath> referencedEntities(Class<?> rootType, PropertyPath path) {
7684

7785
List<PropertyPath> paths = new ArrayList<>();

src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.lang.reflect.Method;
1919

20+
import org.springframework.core.convert.ConversionService;
2021
import org.springframework.data.jdbc.core.DataAccessStrategy;
2122
import org.springframework.data.jdbc.core.EntityRowMapper;
2223
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
@@ -27,33 +28,39 @@
2728
import org.springframework.data.repository.query.QueryLookupStrategy;
2829
import org.springframework.data.repository.query.RepositoryQuery;
2930
import org.springframework.jdbc.core.RowMapper;
31+
import org.springframework.jdbc.core.SingleColumnRowMapper;
3032

3133
/**
3234
* {@link QueryLookupStrategy} for JDBC repositories. Currently only supports annotated queries.
3335
*
3436
* @author Jens Schauder
37+
* @author Kazuki Shimizu
3538
*/
3639
class JdbcQueryLookupStrategy implements QueryLookupStrategy {
3740

3841
private final JdbcMappingContext context;
3942
private final DataAccessStrategy accessStrategy;
43+
private final ConversionService conversionService;
4044

4145
JdbcQueryLookupStrategy(EvaluationContextProvider evaluationContextProvider, JdbcMappingContext context,
4246
DataAccessStrategy accessStrategy) {
4347

4448
this.context = context;
4549
this.accessStrategy = accessStrategy;
50+
this.conversionService = context.getConversions();
4651
}
4752

4853
@Override
4954
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata,
5055
ProjectionFactory projectionFactory, NamedQueries namedQueries) {
5156

5257
JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory);
53-
Class<?> domainType = queryMethod.getReturnedObjectType();
54-
RowMapper<?> rowMapper = new EntityRowMapper<>(context.getRequiredPersistentEntity(domainType),
55-
context.getConversions(), context, accessStrategy);
56-
58+
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
59+
RowMapper<?> rowMapper = context.getSimpleTypeHolder().isSimpleType(returnedObjectType)
60+
? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService)
61+
: new EntityRowMapper<>(context.getRequiredPersistentEntity(returnedObjectType), conversionService,
62+
context, accessStrategy);
5763
return new JdbcRepositoryQuery(queryMethod, context, rowMapper);
5864
}
65+
5966
}

src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import org.springframework.test.context.junit4.rules.SpringMethodRule;
3434
import org.springframework.transaction.annotation.Transactional;
3535

36+
import java.time.LocalDateTime;
37+
import java.util.Date;
3638
import java.util.List;
3739
import java.util.Optional;
3840
import java.util.stream.Stream;
@@ -165,6 +167,48 @@ public void executeCustomQueryWithReturnTypeIsStream() {
165167
.containsExactlyInAnyOrder("a", "b");
166168

167169
}
170+
171+
@Test // DATAJDBC-175
172+
public void executeCustomQueryWithReturnTypeIsNubmer() {
173+
174+
repository.save(dummyEntity("aaa"));
175+
repository.save(dummyEntity("bbb"));
176+
repository.save(dummyEntity("cac"));
177+
178+
int count = repository.countByNameContaining("a");
179+
180+
assertThat(count).isEqualTo(2);
181+
182+
}
183+
184+
@Test // DATAJDBC-175
185+
public void executeCustomQueryWithReturnTypeIsBoolean() {
186+
187+
repository.save(dummyEntity("aaa"));
188+
repository.save(dummyEntity("bbb"));
189+
repository.save(dummyEntity("cac"));
190+
191+
assertThat(repository.existsByNameContaining("a")).isTrue();
192+
assertThat(repository.existsByNameContaining("d")).isFalse();
193+
194+
}
195+
196+
@Test // DATAJDBC-175
197+
public void executeCustomQueryWithReturnTypeIsDate() {
198+
199+
Date now = new Date();
200+
assertThat(repository.nowWithDate()).isAfterOrEqualsTo(now);
201+
202+
}
203+
204+
@Test // DATAJDBC-175
205+
public void executeCustomQueryWithReturnTypeIsLocalDateTimeList() {
206+
207+
LocalDateTime now = LocalDateTime.now();
208+
repository.nowWithLocalDateTimeList() //
209+
.forEach(d -> assertThat(d).isAfterOrEqualTo(now));
210+
211+
}
168212

169213
private DummyEntity dummyEntity(String name) {
170214

@@ -209,5 +253,17 @@ private interface DummyEntityRepository extends CrudRepository<DummyEntity, Long
209253
@Query("SELECT * FROM DUMMYENTITY")
210254
Stream<DummyEntity> findAllWithReturnTypeIsStream();
211255

256+
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
257+
int countByNameContaining(@Param("name") String name);
258+
259+
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
260+
boolean existsByNameContaining(@Param("name") String name);
261+
262+
@Query("VALUES (current_timestamp)")
263+
Date nowWithDate();
264+
265+
@Query("VALUES (current_timestamp),(current_timestamp)")
266+
List<LocalDateTime> nowWithLocalDateTimeList();
267+
212268
}
213269
}

0 commit comments

Comments
 (0)