From 1b1395ab7368eef0464706c3eed733dec8aed224 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 9 Oct 2020 14:33:03 +0200 Subject: [PATCH] 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. --- .../repository/query/JdbcQueryMethod.java | 13 ++- .../data/jdbc/repository/query/Query.java | 13 ++- .../query/StringBasedJdbcQuery.java | 45 +++++--- .../support/JdbcQueryLookupStrategy.java | 15 ++- .../support/JdbcRepositoryFactory.java | 19 +++- .../support/JdbcRepositoryFactoryBean.java | 4 +- .../SimpleJdbcRepositoryEventsUnitTests.java | 4 +- ...yMappingConfigurationIntegrationTests.java | 106 ++++++++++++++---- .../query/StringBasedJdbcQueryUnitTests.java | 24 ++-- .../JdbcQueryLookupStrategyUnitTests.java | 4 +- .../SingleBaseMappingTestConfiguration.java | 75 ------------- .../data/jdbc/testing/TestConfiguration.java | 17 +-- 12 files changed, 178 insertions(+), 161 deletions(-) delete mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/SingleBaseMappingTestConfiguration.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java index 6d22d1b5..7345528a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcQueryMethod.java @@ -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"); } /** diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java index ad170770..5c5eaaf0 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java @@ -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 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 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 ""; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java index 5db1bc24..b5ef83bc 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java @@ -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> 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 rowMapper = determineRowMapper(defaultRowMapper); - executor = getQueryExecution( // + executor = Lazy.of(() -> { + RowMapper 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 determineResultSetExtractor(@Nullable RowMapper rowMapper) { - String resultSetExtractorBean = queryMethod.getResultSetExtractorBean(); - if (resultSetExtractorBean != null && !"ResultSetExtractor".equals(resultSetExtractorBean)) { - return (ResultSetExtractor) 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) beanFactory.getBean(resultSetExtractorRef); } Class resultSetExtractorClass = queryMethod.getResultSetExtractorClass(); @@ -163,12 +170,16 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { } @SuppressWarnings("unchecked") + @Nullable RowMapper determineRowMapper(@Nullable RowMapper defaultMapper) { - String rowMapperBean = queryMethod.getRowMapperBean(); + String rowMapperRef = queryMethod.getRowMapperRef(); - if (rowMapperBean != null && !"RowMapper".equals(rowMapperBean)) { - return (RowMapper) beanfactory.getBean(rowMapperBean); + if (!StringUtils.isEmpty(rowMapperRef)) { + + Assert.notNull(beanFactory, "When a RowMapperRef is specified the BeanFactory must not be null"); + + return (RowMapper) 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; + } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java index 9f655915..f5ca3c33 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java @@ -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) SingleColumnRowMapper.newInstance(returnedObjectType, converter.getConversionService()); } - return (RowMapper) determineDefaultMapper(queryMethod); + return (RowMapper) determineDefaultMapper(queryMethod); } private RowMapper determineDefaultMapper(JdbcQueryMethod queryMethod) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java index 363f5d2a..cc071cf1 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java @@ -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; + } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java index 22de2f3e..e578fbd7 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java @@ -44,6 +44,7 @@ import org.springframework.util.Assert; * @author Christoph Strobl * @author Oliver Gierke * @author Mark Paluch + * @author Hebert Coelho */ public class JdbcRepositoryFactoryBean, S, ID extends Serializable> extends TransactionalRepositoryFactoryBeanSupport implements ApplicationEventPublisherAware { @@ -86,9 +87,10 @@ public class JdbcRepositoryFactoryBean, 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; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java index f3eac239..42bf4811 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java @@ -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); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java index 0ba3e2e7..8d0c33b1 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java @@ -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> { + + @Autowired private CustomerService customerService; + + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + return Arrays.asList(new Car(1L, customerService.process())); + } + + } + + public static class CustomRowMapperBean implements RowMapper { + + @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> { + + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + return singletonList(new Car(1L, CAR_MODEL)); + } + } + + interface CarRepository extends CrudRepository { + + @Query(value = "select * from car", resultSetExtractorClass = CarResultSetExtractor.class) + List customFindAll(); + + @Query(value = "select * from car", resultSetExtractorRef = "CarResultSetExtractorBean") + List findByNameWithResultSetExtractor(); + + @Query(value = "select model from car", rowMapperRef = "CustomRowMapperBean") + List 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 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 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> { - - @Override - public List extractData(ResultSet rs) throws SQLException, DataAccessException { - return Arrays.asList(new Car(1L, CAR_MODEL)); - } - } - - private interface CarRepository extends CrudRepository { - @Query(value = "select * from car", resultSetExtractorClass = CarResultSetExtractor.class) - List customFindAll(); - - @Query(value = "select * from car", resultSetExtractorBean = "CarResultSetExtractorBean") - List findByNameWithResultSetExtractor(); - - @Query(value = "select model from car", rowMapperBean = "CustomRowMapperBean") - List findByNameWithRowMapperBean(); - } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java index b9ef96e8..22a76e4b 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java @@ -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 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 resultSetExtractor = query .determineResultSetExtractor(query.determineRowMapper(defaultRowMapper)); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java index d4bad9b5..5556af94 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java @@ -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); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/SingleBaseMappingTestConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/SingleBaseMappingTestConfiguration.java deleted file mode 100644 index 584e3556..00000000 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/SingleBaseMappingTestConfiguration.java +++ /dev/null @@ -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> { - - @Autowired - private CustomerService customerService; - - @Override - public List extractData(ResultSet rs) throws SQLException, DataAccessException { - return Arrays.asList(new Car(1L, customerService.process())); - } - - } - - public static class CustomRowMapperBean implements RowMapper { - - @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; - } -} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java index 7d0aafb7..508ff134 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java @@ -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) { JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter, dialect, - publisher, namedParameterJdbcTemplate(), beanFactory); + publisher, namedParameterJdbcTemplate()); namedQueries.ifPresent(factory::setNamedQueries); return factory; }