DATAJDBC-182 - Polishing.
Extracted method to maintain a single level of abstraction. Added description to assertion that wasn't obvious to me. Added JavaDoc on existing method. Commented repository methods in test with issue ids to ease understanding the purpose of each method.
This commit is contained in:
@@ -56,18 +56,21 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
|||||||
|
|
||||||
JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory);
|
JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory);
|
||||||
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
|
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
|
||||||
RowMapper<?> rowMapper = null;
|
|
||||||
if (!queryMethod.isModifyingQuery()) {
|
RowMapper<?> rowMapper = queryMethod.isModifyingQuery() ? null : createRowMapper(returnedObjectType);
|
||||||
rowMapper = context.getSimpleTypeHolder().isSimpleType(returnedObjectType)
|
|
||||||
? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService)
|
|
||||||
: new EntityRowMapper<>( //
|
|
||||||
context.getRequiredPersistentEntity(returnedObjectType), //
|
|
||||||
conversionService, //
|
|
||||||
context, //
|
|
||||||
accessStrategy //
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new JdbcRepositoryQuery(queryMethod, context, rowMapper);
|
return new JdbcRepositoryQuery(queryMethod, context, rowMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RowMapper<?> createRowMapper(Class<?> returnedObjectType) {
|
||||||
|
|
||||||
|
return context.getSimpleTypeHolder().isSimpleType(returnedObjectType)
|
||||||
|
? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService)
|
||||||
|
: new EntityRowMapper<>( //
|
||||||
|
context.getRequiredPersistentEntity(returnedObjectType), //
|
||||||
|
conversionService, //
|
||||||
|
context, //
|
||||||
|
accessStrategy //
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.springframework.data.jdbc.repository.query.Query;
|
|||||||
import org.springframework.data.projection.ProjectionFactory;
|
import org.springframework.data.projection.ProjectionFactory;
|
||||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||||
import org.springframework.data.repository.query.QueryMethod;
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link QueryMethod} implementation that implements a method by executing the query from a {@link Query} annotation on
|
* {@link QueryMethod} implementation that implements a method by executing the query from a {@link Query} annotation on
|
||||||
@@ -44,6 +45,12 @@ public class JdbcQueryMethod extends QueryMethod {
|
|||||||
this.method = method;
|
this.method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the annotated query if it exists.
|
||||||
|
*
|
||||||
|
* @return May be {@code null}.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
public String getAnnotatedQuery() {
|
public String getAnnotatedQuery() {
|
||||||
|
|
||||||
Query queryAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Query.class);
|
Query queryAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Query.class);
|
||||||
|
|||||||
@@ -15,6 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.jdbc.repository.query;
|
package org.springframework.data.jdbc.repository.query;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -33,14 +41,6 @@ import org.springframework.test.context.junit4.rules.SpringClassRule;
|
|||||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
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;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the execution of queries from {@link Query} annotations on repository methods.
|
* Tests the execution of queries from {@link Query} annotations on repository methods.
|
||||||
*
|
*
|
||||||
@@ -51,13 +51,10 @@ import static org.assertj.core.api.Assertions.*;
|
|||||||
@Transactional
|
@Transactional
|
||||||
public class QueryAnnotationHsqlIntegrationTests {
|
public class QueryAnnotationHsqlIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired DummyEntityRepository repository;
|
||||||
DummyEntityRepository repository;
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule public static final SpringClassRule classRule = new SpringClassRule();
|
||||||
public static final SpringClassRule classRule = new SpringClassRule();
|
@Rule public SpringMethodRule methodRule = new SpringMethodRule();
|
||||||
@Rule
|
|
||||||
public SpringMethodRule methodRule = new SpringMethodRule();
|
|
||||||
|
|
||||||
@Test // DATAJDBC-164
|
@Test // DATAJDBC-164
|
||||||
public void executeCustomQueryWithoutParameter() {
|
public void executeCustomQueryWithoutParameter() {
|
||||||
@@ -167,7 +164,7 @@ public class QueryAnnotationHsqlIntegrationTests {
|
|||||||
.containsExactlyInAnyOrder("a", "b");
|
.containsExactlyInAnyOrder("a", "b");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAJDBC-175
|
@Test // DATAJDBC-175
|
||||||
public void executeCustomQueryWithReturnTypeIsNubmer() {
|
public void executeCustomQueryWithReturnTypeIsNubmer() {
|
||||||
|
|
||||||
@@ -211,36 +208,40 @@ public class QueryAnnotationHsqlIntegrationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAJDBC-182
|
@Test // DATAJDBC-182
|
||||||
public void executeCustomModifyingQueryWithReturnTypeIsNumber() {
|
public void executeCustomModifyingQueryWithReturnTypeNumber() {
|
||||||
|
|
||||||
DummyEntity entity = dummyEntity("a");
|
DummyEntity entity = dummyEntity("a");
|
||||||
repository.save(entity);
|
repository.save(entity);
|
||||||
|
|
||||||
assertThat(repository.updateName(entity.id, "b")).isEqualTo(1);
|
assertThat(repository.updateName(entity.id, "b")).isEqualTo(1);
|
||||||
assertThat(repository.updateName(9999L, "b")).isEqualTo(0);
|
assertThat(repository.updateName(9999L, "c")).isEqualTo(0);
|
||||||
assertThat(repository.findById(entity.id)).isPresent().map(e -> e.name).contains("b");
|
|
||||||
|
|
||||||
|
assertThat(repository.findById(entity.id)) //
|
||||||
|
.describedAs("update was not performed as expected") //
|
||||||
|
.isPresent() //
|
||||||
|
.map(e -> e.name).contains("b");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAJDBC-182
|
@Test // DATAJDBC-182
|
||||||
public void executeCustomModifyingQueryWithReturnTypeIsBoolean() {
|
public void executeCustomModifyingQueryWithReturnTypeBoolean() {
|
||||||
|
|
||||||
DummyEntity entity = dummyEntity("a");
|
DummyEntity entity = dummyEntity("a");
|
||||||
repository.save(entity);
|
repository.save(entity);
|
||||||
|
|
||||||
assertThat(repository.deleteByName("a")).isTrue();
|
assertThat(repository.deleteByName("a")).isTrue();
|
||||||
assertThat(repository.deleteByName("b")).isFalse();
|
assertThat(repository.deleteByName("b")).isFalse();
|
||||||
assertThat(repository.findById(entity.id)).isNotPresent();
|
|
||||||
|
|
||||||
|
assertThat(repository.findById(entity.id)) //
|
||||||
|
.describedAs("delete not performed as expected") //
|
||||||
|
.isNotPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAJDBC-182
|
@Test // DATAJDBC-182
|
||||||
public void executeCustomModifyingQueryWithReturnTypeIsVoid() {
|
public void executeCustomModifyingQueryWithReturnTypeVoid() {
|
||||||
|
|
||||||
repository.insert("Spring Data JDBC");
|
repository.insert("Spring Data JDBC");
|
||||||
|
|
||||||
assertThat(repository.findByNameAsEntity("Spring Data JDBC")).isNotNull();
|
assertThat(repository.findByNameAsEntity("Spring Data JDBC")).isNotNull();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DummyEntity dummyEntity(String name) {
|
private DummyEntity dummyEntity(String name) {
|
||||||
@@ -263,49 +264,59 @@ public class QueryAnnotationHsqlIntegrationTests {
|
|||||||
|
|
||||||
private static class DummyEntity {
|
private static class DummyEntity {
|
||||||
|
|
||||||
@Id
|
@Id Long id;
|
||||||
Long id;
|
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
|
private interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
|
||||||
|
|
||||||
|
// DATAJDBC-164
|
||||||
@Query("SELECT * FROM DUMMYENTITY WHERE lower(name) <> name")
|
@Query("SELECT * FROM DUMMYENTITY WHERE lower(name) <> name")
|
||||||
List<DummyEntity> findByNameContainingCapitalLetter();
|
List<DummyEntity> findByNameContainingCapitalLetter();
|
||||||
|
|
||||||
|
// DATAJDBC-164
|
||||||
@Query("SELECT * FROM DUMMYENTITY WHERE name < :upper and name > :lower")
|
@Query("SELECT * FROM DUMMYENTITY WHERE name < :upper and name > :lower")
|
||||||
List<DummyEntity> findByNamedRangeWithNamedParameter(@Param("lower") String lower, @Param("upper") String upper);
|
List<DummyEntity> findByNamedRangeWithNamedParameter(@Param("lower") String lower, @Param("upper") String upper);
|
||||||
|
|
||||||
@Query("SELECT * FROM DUMMYENTITY WHERE name = :name")
|
@Query("SELECT * FROM DUMMYENTITY WHERE name = :name")
|
||||||
Optional<DummyEntity> findByNameAsOptional(@Param("name") String name);
|
Optional<DummyEntity> findByNameAsOptional(@Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-172
|
||||||
@Query("SELECT * FROM DUMMYENTITY WHERE name = :name")
|
@Query("SELECT * FROM DUMMYENTITY WHERE name = :name")
|
||||||
DummyEntity findByNameAsEntity(@Param("name") String name);
|
DummyEntity findByNameAsEntity(@Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-172
|
||||||
@Query("SELECT * FROM DUMMYENTITY")
|
@Query("SELECT * FROM DUMMYENTITY")
|
||||||
Stream<DummyEntity> findAllWithReturnTypeIsStream();
|
Stream<DummyEntity> findAllWithReturnTypeIsStream();
|
||||||
|
|
||||||
|
// DATAJDBC-175
|
||||||
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
|
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
|
||||||
int countByNameContaining(@Param("name") String name);
|
int countByNameContaining(@Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-175
|
||||||
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
|
@Query("SELECT count(*) FROM DUMMYENTITY WHERE name like '%' || :name || '%'")
|
||||||
boolean existsByNameContaining(@Param("name") String name);
|
boolean existsByNameContaining(@Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-175
|
||||||
@Query("VALUES (current_timestamp)")
|
@Query("VALUES (current_timestamp)")
|
||||||
Date nowWithDate();
|
Date nowWithDate();
|
||||||
|
|
||||||
|
// DATAJDBC-175
|
||||||
@Query("VALUES (current_timestamp),(current_timestamp)")
|
@Query("VALUES (current_timestamp),(current_timestamp)")
|
||||||
List<LocalDateTime> nowWithLocalDateTimeList();
|
List<LocalDateTime> nowWithLocalDateTimeList();
|
||||||
|
|
||||||
|
// DATAJDBC-182
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("UPDATE DUMMYENTITY SET name = :name WHERE id = :id")
|
@Query("UPDATE DUMMYENTITY SET name = :name WHERE id = :id")
|
||||||
int updateName(@Param("id") Long id, @Param("name") String name);
|
int updateName(@Param("id") Long id, @Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-182
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("DELETE FROM DUMMYENTITY WHERE name = :name")
|
@Query("DELETE FROM DUMMYENTITY WHERE name = :name")
|
||||||
boolean deleteByName(@Param("name") String name);
|
boolean deleteByName(@Param("name") String name);
|
||||||
|
|
||||||
|
// DATAJDBC-182
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("INSERT INTO DUMMYENTITY (name) VALUES(:name)")
|
@Query("INSERT INTO DUMMYENTITY (name) VALUES(:name)")
|
||||||
void insert(@Param("name") String name);
|
void insert(@Param("name") String name);
|
||||||
|
|||||||
Reference in New Issue
Block a user