DATAJDBC-430 - Polishing.
Renames *Bean annotation attributes to *Ref to match other similar attributes. Removes additional arguments from constructors of public classes in order to avoid breaking the API. Gathers application context configuration for StringBasedJdbcQueryMappingConfigurationIntegrationTests in a single java file. Formatting. Adds the author tag. Changes default value of references to the empty String. Original pull request: #249.
This commit is contained in:
@@ -46,6 +46,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Jens Schauder
|
||||
* @author Kazuki Shimizu
|
||||
* @author Moises Cisneros
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
public class JdbcQueryMethod extends QueryMethod {
|
||||
|
||||
@@ -175,13 +176,13 @@ public class JdbcQueryMethod extends QueryMethod {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bean to be used as {@link org.springframework.jdbc.core.RowMapper}
|
||||
* Returns the name of the bean to be used as {@link org.springframework.jdbc.core.RowMapper}
|
||||
*
|
||||
* @return May be {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
String getRowMapperBean() {
|
||||
return getMergedAnnotationAttribute("rowMapperBean");
|
||||
String getRowMapperRef() {
|
||||
return getMergedAnnotationAttribute("rowMapperRef");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,13 +196,13 @@ public class JdbcQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean to be used as {@link org.springframework.jdbc.core.ResultSetExtractor}
|
||||
* Returns the bean name to be used as {@link org.springframework.jdbc.core.ResultSetExtractor}
|
||||
*
|
||||
* @return May be {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
String getResultSetExtractorBean() {
|
||||
return getMergedAnnotationAttribute("resultSetExtractorBean");
|
||||
String getResultSetExtractorRef() {
|
||||
return getMergedAnnotationAttribute("resultSetExtractorRef");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.jdbc.core.RowMapper;
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Moises Cisneros
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -57,10 +58,12 @@ public @interface Query {
|
||||
Class<? extends RowMapper> rowMapperClass() default RowMapper.class;
|
||||
|
||||
/**
|
||||
* Optional bean of type {@link RowMapper} to use to convert the result of the query to domain class instances. Cannot be used
|
||||
* Optional name of a bean of type {@link RowMapper} to use to convert the result of the query to domain class instances. Cannot be used
|
||||
* along with {@link #resultSetExtractorClass()} only one of the two can be set.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
String rowMapperBean() default "RowMapper";
|
||||
String rowMapperRef() default "";
|
||||
|
||||
/**
|
||||
* Optional {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. Cannot be
|
||||
@@ -69,8 +72,10 @@ public @interface Query {
|
||||
Class<? extends ResultSetExtractor> resultSetExtractorClass() default ResultSetExtractor.class;
|
||||
|
||||
/**
|
||||
* Optional bean of type {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. Cannot be
|
||||
* Optional name of a bean of type {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. Cannot be
|
||||
* used along with {@link #rowMapperClass()} only one of the two can be set.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
String resultSetExtractorBean() default "ResultSetExtractor";
|
||||
String resultSetExtractorRef() default "";
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ import org.springframework.data.jdbc.core.convert.JdbcValue;
|
||||
import org.springframework.data.jdbc.support.JdbcUtil;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -43,6 +45,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Oliver Gierke
|
||||
* @author Maciej Walkowiak
|
||||
* @author Mark Paluch
|
||||
* @author Hebert Coelho
|
||||
* @since 2.0
|
||||
*/
|
||||
public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
@@ -50,9 +53,9 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
private static final String PARAMETER_NEEDS_TO_BE_NAMED = "For queries with named parameters you need to provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.";
|
||||
|
||||
private final JdbcQueryMethod queryMethod;
|
||||
private final JdbcQueryExecution<?> executor;
|
||||
private final Lazy<JdbcQueryExecution<?>> executor;
|
||||
private final JdbcConverter converter;
|
||||
private BeanFactory beanfactory;
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedJdbcQuery} for the given {@link JdbcQueryMethod}, {@link RelationalMappingContext}
|
||||
@@ -63,20 +66,20 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
* @param defaultRowMapper can be {@literal null} (only in case of a modifying query).
|
||||
*/
|
||||
public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOperations operations,
|
||||
@Nullable RowMapper<?> defaultRowMapper, JdbcConverter converter, BeanFactory beanfactory) {
|
||||
@Nullable RowMapper<?> defaultRowMapper, JdbcConverter converter) {
|
||||
|
||||
super(queryMethod, operations, defaultRowMapper);
|
||||
|
||||
this.queryMethod = queryMethod;
|
||||
this.converter = converter;
|
||||
this.beanfactory = beanfactory;
|
||||
|
||||
RowMapper<Object> rowMapper = determineRowMapper(defaultRowMapper);
|
||||
executor = getQueryExecution( //
|
||||
executor = Lazy.of(() -> {
|
||||
RowMapper<Object> rowMapper = determineRowMapper(defaultRowMapper);
|
||||
return getQueryExecution( //
|
||||
queryMethod, //
|
||||
determineResultSetExtractor(rowMapper != defaultRowMapper ? rowMapper : null), //
|
||||
rowMapper //
|
||||
);
|
||||
);});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,7 +88,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] objects) {
|
||||
return executor.execute(determineQuery(), this.bindParameters(objects));
|
||||
return executor.get().execute(determineQuery(), this.bindParameters(objects));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -97,7 +100,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
return queryMethod;
|
||||
}
|
||||
|
||||
MapSqlParameterSource bindParameters(Object[] objects) {
|
||||
private MapSqlParameterSource bindParameters(Object[] objects) {
|
||||
|
||||
MapSqlParameterSource parameters = new MapSqlParameterSource();
|
||||
|
||||
@@ -140,10 +143,14 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
@Nullable
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
ResultSetExtractor<Object> determineResultSetExtractor(@Nullable RowMapper<Object> rowMapper) {
|
||||
String resultSetExtractorBean = queryMethod.getResultSetExtractorBean();
|
||||
|
||||
if (resultSetExtractorBean != null && !"ResultSetExtractor".equals(resultSetExtractorBean)) {
|
||||
return (ResultSetExtractor<Object>) beanfactory.getBean(resultSetExtractorBean);
|
||||
String resultSetExtractorRef = queryMethod.getResultSetExtractorRef();
|
||||
|
||||
if (!StringUtils.isEmpty(resultSetExtractorRef)) {
|
||||
|
||||
Assert.notNull(beanFactory, "When a ResultSetExtractorRef is specified the BeanFactory must not be null");
|
||||
|
||||
return (ResultSetExtractor<Object>) beanFactory.getBean(resultSetExtractorRef);
|
||||
}
|
||||
|
||||
Class<? extends ResultSetExtractor> resultSetExtractorClass = queryMethod.getResultSetExtractorClass();
|
||||
@@ -163,12 +170,16 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
RowMapper<Object> determineRowMapper(@Nullable RowMapper<?> defaultMapper) {
|
||||
|
||||
String rowMapperBean = queryMethod.getRowMapperBean();
|
||||
String rowMapperRef = queryMethod.getRowMapperRef();
|
||||
|
||||
if (rowMapperBean != null && !"RowMapper".equals(rowMapperBean)) {
|
||||
return (RowMapper<Object>) beanfactory.getBean(rowMapperBean);
|
||||
if (!StringUtils.isEmpty(rowMapperRef)) {
|
||||
|
||||
Assert.notNull(beanFactory, "When a RowMapperRef is specified the BeanFactory must not be null");
|
||||
|
||||
return (RowMapper<Object>) beanFactory.getBean(rowMapperRef);
|
||||
}
|
||||
|
||||
Class<?> rowMapperClass = queryMethod.getRowMapperClass();
|
||||
@@ -183,4 +194,8 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
|
||||
private static boolean isUnconfigured(@Nullable Class<?> configuredClass, Class<?> defaultClass) {
|
||||
return configuredClass == null || configuredClass == defaultClass;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.springframework.util.Assert;
|
||||
* @author Mark Paluch
|
||||
* @author Maciej Walkowiak
|
||||
* @author Moises Cisneros
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
@@ -64,9 +65,9 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
private final Dialect dialect;
|
||||
private final QueryMappingConfiguration queryMappingConfiguration;
|
||||
private final NamedParameterJdbcOperations operations;
|
||||
private BeanFactory beanfactory;
|
||||
private final BeanFactory beanfactory;
|
||||
|
||||
public JdbcQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks,
|
||||
JdbcQueryLookupStrategy(ApplicationEventPublisher publisher, @Nullable EntityCallbacks callbacks,
|
||||
RelationalMappingContext context, JdbcConverter converter, Dialect dialect,
|
||||
QueryMappingConfiguration queryMappingConfiguration, NamedParameterJdbcOperations operations,
|
||||
BeanFactory beanfactory) {
|
||||
@@ -103,12 +104,14 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
if (namedQueries.hasQuery(queryMethod.getNamedQueryName()) || queryMethod.hasAnnotatedQuery()) {
|
||||
|
||||
RowMapper<?> mapper = queryMethod.isModifyingQuery() ? null : createMapper(queryMethod);
|
||||
return new StringBasedJdbcQuery(queryMethod, operations, mapper, converter, beanfactory);
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, mapper, converter);
|
||||
query.setBeanFactory(beanfactory);
|
||||
return query;
|
||||
} else {
|
||||
return new PartTreeJdbcQuery(context, queryMethod, dialect, converter, operations, createMapper(queryMethod));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw QueryCreationException.create(queryMethod, e.getMessage());
|
||||
throw QueryCreationException.create(queryMethod, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +123,10 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
RelationalPersistentEntity<?> persistentEntity = context.getPersistentEntity(returnedObjectType);
|
||||
|
||||
if (persistentEntity == null) {
|
||||
return (RowMapper) SingleColumnRowMapper.newInstance(returnedObjectType, converter.getConversionService());
|
||||
return (RowMapper<Object>) SingleColumnRowMapper.newInstance(returnedObjectType, converter.getConversionService());
|
||||
}
|
||||
|
||||
return (RowMapper) determineDefaultMapper(queryMethod);
|
||||
return (RowMapper<Object>) determineDefaultMapper(queryMethod);
|
||||
}
|
||||
|
||||
private RowMapper<?> determineDefaultMapper(JdbcQueryMethod queryMethod) {
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.util.Assert;
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
@@ -54,7 +55,7 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
private final DataAccessStrategy accessStrategy;
|
||||
private final NamedParameterJdbcOperations operations;
|
||||
private final Dialect dialect;
|
||||
private BeanFactory beanfactory;
|
||||
@Nullable private BeanFactory beanFactory;
|
||||
|
||||
private QueryMappingConfiguration queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
|
||||
private EntityCallbacks entityCallbacks;
|
||||
@@ -72,7 +73,7 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
*/
|
||||
public JdbcRepositoryFactory(DataAccessStrategy dataAccessStrategy, RelationalMappingContext context,
|
||||
JdbcConverter converter, Dialect dialect, ApplicationEventPublisher publisher,
|
||||
NamedParameterJdbcOperations operations, BeanFactory beanfactory) {
|
||||
NamedParameterJdbcOperations operations) {
|
||||
|
||||
Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null!");
|
||||
Assert.notNull(context, "RelationalMappingContext must not be null!");
|
||||
@@ -86,7 +87,6 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
this.dialect = dialect;
|
||||
this.accessStrategy = dataAccessStrategy;
|
||||
this.operations = operations;
|
||||
this.beanfactory = beanfactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +122,8 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
template.setEntityCallbacks(entityCallbacks);
|
||||
}
|
||||
|
||||
RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(repositoryInformation.getDomainType());
|
||||
RelationalPersistentEntity<?> persistentEntity = context
|
||||
.getRequiredPersistentEntity(repositoryInformation.getDomainType());
|
||||
|
||||
return getTargetRepositoryViaReflection(repositoryInformation.getRepositoryBaseClass(), template, persistentEntity);
|
||||
}
|
||||
@@ -145,7 +146,7 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
|
||||
return Optional.of(new JdbcQueryLookupStrategy(publisher, entityCallbacks, context, converter, dialect,
|
||||
queryMappingConfiguration, operations, beanfactory));
|
||||
queryMappingConfiguration, operations, beanFactory));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,4 +156,12 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
public void setEntityCallbacks(EntityCallbacks entityCallbacks) {
|
||||
this.entityCallbacks = entityCallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param beanFactory the {@link BeanFactory} used for looking up {@link org.springframework.jdbc.core.RowMapper} and
|
||||
* {@link org.springframework.jdbc.core.ResultSetExtractor} beans.
|
||||
*/
|
||||
public void setBeanFactory(@Nullable BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.springframework.util.Assert;
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
|
||||
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> implements ApplicationEventPublisherAware {
|
||||
@@ -86,9 +87,10 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
|
||||
protected RepositoryFactorySupport doCreateRepositoryFactory() {
|
||||
|
||||
JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory(dataAccessStrategy, mappingContext,
|
||||
converter, dialect, publisher, operations, beanFactory);
|
||||
converter, dialect, publisher, operations);
|
||||
jdbcRepositoryFactory.setQueryMappingConfiguration(queryMappingConfiguration);
|
||||
jdbcRepositoryFactory.setEntityCallbacks(entityCallbacks);
|
||||
jdbcRepositoryFactory.setBeanFactory(beanFactory);
|
||||
|
||||
return jdbcRepositoryFactory;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.assertj.core.groups.Tuple;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -83,7 +82,6 @@ public class SimpleJdbcRepositoryEventsUnitTests {
|
||||
|
||||
DummyEntityRepository repository;
|
||||
DefaultDataAccessStrategy dataAccessStrategy;
|
||||
BeanFactory beanFactory = mock(BeanFactory.class);
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
@@ -101,7 +99,7 @@ public class SimpleJdbcRepositoryEventsUnitTests {
|
||||
doReturn(true).when(dataAccessStrategy).update(any(), any());
|
||||
|
||||
JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter,
|
||||
H2Dialect.INSTANCE, publisher, operations, beanFactory);
|
||||
H2Dialect.INSTANCE, publisher, operations);
|
||||
|
||||
this.repository = factory.getRepository(DummyEntityRepository.class);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.jdbc.testing.SingleBaseMappingTestConfiguration.VALUE_PROCESSED_BY_SERVICE;
|
||||
import static java.util.Collections.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -31,13 +34,14 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration;
|
||||
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
|
||||
import org.springframework.data.jdbc.repository.query.Query;
|
||||
import org.springframework.data.jdbc.testing.SingleBaseMappingTestConfiguration.Car;
|
||||
import org.springframework.data.jdbc.testing.TestConfiguration;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
@@ -48,12 +52,14 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* Very simple use cases for creation and usage of {@link ResultSetExtractor}s in JdbcRepository.
|
||||
*
|
||||
* @author Evgeni Dimitrov
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@Transactional
|
||||
public class StringBasedJdbcQueryMappingConfigurationIntegrationTests {
|
||||
|
||||
private final static String CAR_MODEL = "ResultSetExtractor Car";
|
||||
private final static String VALUE_PROCESSED_BY_SERVICE = "Value Processed by Service";
|
||||
|
||||
@Configuration
|
||||
@Import(TestConfiguration.class)
|
||||
@@ -69,6 +75,76 @@ public class StringBasedJdbcQueryMappingConfigurationIntegrationTests {
|
||||
QueryMappingConfiguration mappers() {
|
||||
return new DefaultQueryMappingConfiguration();
|
||||
}
|
||||
|
||||
@Bean(value = "CarResultSetExtractorBean")
|
||||
public CarResultSetExtractorBean resultSetExtractorBean() {
|
||||
return new CarResultSetExtractorBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomerService service() {
|
||||
return new CustomerService();
|
||||
}
|
||||
|
||||
@Bean(value = "CustomRowMapperBean")
|
||||
public CustomRowMapperBean rowMapperBean() {
|
||||
return new CustomRowMapperBean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CarResultSetExtractorBean implements ResultSetExtractor<List<Car>> {
|
||||
|
||||
@Autowired private CustomerService customerService;
|
||||
|
||||
@Override
|
||||
public List<Car> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
return Arrays.asList(new Car(1L, customerService.process()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomRowMapperBean implements RowMapper<String> {
|
||||
|
||||
@Autowired private CustomerService customerService;
|
||||
|
||||
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
return customerService.process();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomerService {
|
||||
public String process() {
|
||||
return VALUE_PROCESSED_BY_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class Car {
|
||||
|
||||
@Id private Long id;
|
||||
private String model;
|
||||
}
|
||||
|
||||
static class CarResultSetExtractor implements ResultSetExtractor<List<Car>> {
|
||||
|
||||
@Override
|
||||
public List<Car> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
return singletonList(new Car(1L, CAR_MODEL));
|
||||
}
|
||||
}
|
||||
|
||||
interface CarRepository extends CrudRepository<Car, Long> {
|
||||
|
||||
@Query(value = "select * from car", resultSetExtractorClass = CarResultSetExtractor.class)
|
||||
List<Car> customFindAll();
|
||||
|
||||
@Query(value = "select * from car", resultSetExtractorRef = "CarResultSetExtractorBean")
|
||||
List<Car> findByNameWithResultSetExtractor();
|
||||
|
||||
@Query(value = "select model from car", rowMapperRef = "CustomRowMapperBean")
|
||||
List<String> findByNameWithRowMapperBean();
|
||||
}
|
||||
|
||||
@ClassRule public static final SpringClassRule classRule = new SpringClassRule();
|
||||
@@ -88,7 +164,8 @@ public class StringBasedJdbcQueryMappingConfigurationIntegrationTests {
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-430
|
||||
public void customFindWithRowMapperSupportingInjection() {
|
||||
public void customFindWithRowMapperBeanSupportingInjection() {
|
||||
|
||||
carRepository.save(new Car(null, "Some model"));
|
||||
List<String> names = carRepository.findByNameWithRowMapperBean();
|
||||
|
||||
@@ -97,7 +174,8 @@ public class StringBasedJdbcQueryMappingConfigurationIntegrationTests {
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-430
|
||||
public void customFindWithResultSetExtractorSupportingInjection() {
|
||||
public void customFindWithResultSetExtractorBeanSupportingInjection() {
|
||||
|
||||
carRepository.save(new Car(null, "Some model"));
|
||||
Iterable<Car> cars = carRepository.findByNameWithResultSetExtractor();
|
||||
|
||||
@@ -105,22 +183,4 @@ public class StringBasedJdbcQueryMappingConfigurationIntegrationTests {
|
||||
assertThat(cars).allMatch(car -> VALUE_PROCESSED_BY_SERVICE.equals(car.getModel()));
|
||||
}
|
||||
|
||||
static class CarResultSetExtractor implements ResultSetExtractor<List<Car>> {
|
||||
|
||||
@Override
|
||||
public List<Car> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
return Arrays.asList(new Car(1L, CAR_MODEL));
|
||||
}
|
||||
}
|
||||
|
||||
private interface CarRepository extends CrudRepository<Car, Long> {
|
||||
@Query(value = "select * from car", resultSetExtractorClass = CarResultSetExtractor.class)
|
||||
List<Car> customFindAll();
|
||||
|
||||
@Query(value = "select * from car", resultSetExtractorBean = "CarResultSetExtractorBean")
|
||||
List<Car> findByNameWithResultSetExtractor();
|
||||
|
||||
@Query(value = "select model from car", rowMapperBean = "CustomRowMapperBean")
|
||||
List<String> findByNameWithRowMapperBean();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.*;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -54,7 +55,6 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
NamedParameterJdbcOperations operations;
|
||||
RelationalMappingContext context;
|
||||
JdbcConverter converter;
|
||||
BeanFactory beanFactory;
|
||||
|
||||
@Before
|
||||
public void setup() throws NoSuchMethodException {
|
||||
@@ -69,7 +69,6 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
this.operations = mock(NamedParameterJdbcOperations.class);
|
||||
this.context = mock(RelationalMappingContext.class, RETURNS_DEEP_STUBS);
|
||||
this.converter = new BasicJdbcConverter(context, mock(RelationResolver.class));
|
||||
this.beanFactory = mock(BeanFactory.class);
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-165
|
||||
@@ -78,16 +77,23 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
doReturn(null).when(queryMethod).getDeclaredQuery();
|
||||
|
||||
Assertions.assertThatExceptionOfType(IllegalStateException.class) //
|
||||
.isThrownBy(() -> new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory)
|
||||
.isThrownBy(() -> createQuery()
|
||||
.execute(new Object[] {}));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StringBasedJdbcQuery createQuery() {
|
||||
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-165
|
||||
public void defaultRowMapperIsUsedByDefault() {
|
||||
|
||||
doReturn("some sql statement").when(queryMethod).getDeclaredQuery();
|
||||
doReturn(RowMapper.class).when(queryMethod).getRowMapperClass();
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory);
|
||||
StringBasedJdbcQuery query = createQuery();
|
||||
|
||||
assertThat(query.determineRowMapper(defaultRowMapper)).isEqualTo(defaultRowMapper);
|
||||
}
|
||||
@@ -96,7 +102,7 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
public void defaultRowMapperIsUsedForNull() {
|
||||
|
||||
doReturn("some sql statement").when(queryMethod).getDeclaredQuery();
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory);
|
||||
StringBasedJdbcQuery query = createQuery();
|
||||
|
||||
assertThat(query.determineRowMapper(defaultRowMapper)).isEqualTo(defaultRowMapper);
|
||||
}
|
||||
@@ -107,7 +113,7 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
doReturn("some sql statement").when(queryMethod).getDeclaredQuery();
|
||||
doReturn(CustomRowMapper.class).when(queryMethod).getRowMapperClass();
|
||||
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory);
|
||||
StringBasedJdbcQuery query = createQuery();
|
||||
|
||||
assertThat(query.determineRowMapper(defaultRowMapper)).isInstanceOf(CustomRowMapper.class);
|
||||
}
|
||||
@@ -118,9 +124,9 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
doReturn("some sql statement").when(queryMethod).getDeclaredQuery();
|
||||
doReturn(CustomResultSetExtractor.class).when(queryMethod).getResultSetExtractorClass();
|
||||
|
||||
new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory).execute(new Object[] {});
|
||||
createQuery().execute(new Object[] {});
|
||||
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory);
|
||||
StringBasedJdbcQuery query = createQuery();
|
||||
|
||||
ResultSetExtractor<Object> resultSetExtractor = query.determineResultSetExtractor(defaultRowMapper);
|
||||
|
||||
@@ -137,7 +143,7 @@ public class StringBasedJdbcQueryUnitTests {
|
||||
doReturn(CustomResultSetExtractor.class).when(queryMethod).getResultSetExtractorClass();
|
||||
doReturn(CustomRowMapper.class).when(queryMethod).getRowMapperClass();
|
||||
|
||||
StringBasedJdbcQuery query = new StringBasedJdbcQuery(queryMethod, operations, defaultRowMapper, converter, beanFactory);
|
||||
StringBasedJdbcQuery query = createQuery();
|
||||
|
||||
ResultSetExtractor<Object> resultSetExtractor = query
|
||||
.determineResultSetExtractor(query.determineRowMapper(defaultRowMapper));
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Maciej Walkowiak
|
||||
* @author Evgeni Dimitrov
|
||||
* @author Mark Paluch
|
||||
* @author Hebert Coelho
|
||||
*/
|
||||
public class JdbcQueryLookupStrategyUnitTests {
|
||||
|
||||
@@ -62,7 +63,6 @@ public class JdbcQueryLookupStrategyUnitTests {
|
||||
ProjectionFactory projectionFactory = mock(ProjectionFactory.class);
|
||||
RepositoryMetadata metadata;
|
||||
NamedQueries namedQueries = mock(NamedQueries.class);
|
||||
BeanFactory beanFactory = mock(BeanFactory.class);
|
||||
NamedParameterJdbcOperations operations = mock(NamedParameterJdbcOperations.class);
|
||||
|
||||
@Before
|
||||
@@ -92,7 +92,7 @@ public class JdbcQueryLookupStrategyUnitTests {
|
||||
private RepositoryQuery getRepositoryQuery(String name, QueryMappingConfiguration mappingConfiguration) {
|
||||
|
||||
JdbcQueryLookupStrategy queryLookupStrategy = new JdbcQueryLookupStrategy(publisher, callbacks, mappingContext,
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, beanFactory);
|
||||
converter, H2Dialect.INSTANCE, mappingConfiguration, operations, null);
|
||||
|
||||
Method method = ReflectionUtils.findMethod(MyRepository.class, name);
|
||||
return queryLookupStrategy.resolveQuery(method, metadata, projectionFactory, namedQueries);
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package org.springframework.data.jdbc.testing;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
@Configuration
|
||||
public class SingleBaseMappingTestConfiguration {
|
||||
|
||||
public final static String VALUE_PROCESSED_BY_SERVICE = "Value Processed by Service";
|
||||
|
||||
@Bean(value = "CarResultSetExtractorBean")
|
||||
public CarResultSetExtractorBean resultSetExtractorBean() {
|
||||
return new CarResultSetExtractorBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomerService service() {
|
||||
return new CustomerService();
|
||||
}
|
||||
|
||||
@Bean(value = "CustomRowMapperBean")
|
||||
public CustomRowMapperBean rowMapperBean() {
|
||||
return new CustomRowMapperBean();
|
||||
}
|
||||
|
||||
public static class CarResultSetExtractorBean implements ResultSetExtractor<List<Car>> {
|
||||
|
||||
@Autowired
|
||||
private CustomerService customerService;
|
||||
|
||||
@Override
|
||||
public List<Car> extractData(ResultSet rs) throws SQLException, DataAccessException {
|
||||
return Arrays.asList(new Car(1L, customerService.process()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomRowMapperBean implements RowMapper<String> {
|
||||
|
||||
@Autowired
|
||||
private CustomerService customerService;
|
||||
|
||||
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
return customerService.process();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomerService {
|
||||
public String process() {
|
||||
return VALUE_PROCESSED_BY_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class Car {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
private String model;
|
||||
}
|
||||
}
|
||||
@@ -15,24 +15,19 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.testing;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.convert.CustomConversions;
|
||||
import org.springframework.data.jdbc.core.convert.BasicJdbcConverter;
|
||||
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
|
||||
@@ -49,8 +44,6 @@ import org.springframework.data.relational.core.dialect.Dialect;
|
||||
import org.springframework.data.relational.core.mapping.NamingStrategy;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
@@ -80,7 +73,7 @@ public class TestConfiguration {
|
||||
Dialect dialect, JdbcConverter converter, Optional<NamedQueries> namedQueries) {
|
||||
|
||||
JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter, dialect,
|
||||
publisher, namedParameterJdbcTemplate(), beanFactory);
|
||||
publisher, namedParameterJdbcTemplate());
|
||||
namedQueries.ifPresent(factory::setNamedQueries);
|
||||
return factory;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user