Skip to content

Commit 97a625c

Browse files
committed
GH-1006 included QueryMappingConfiguration for all part tree queries
1 parent b3040a1 commit 97a625c

29 files changed

+222
-40
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategyFactory.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* {@link DataAccessStrategy} for consistent access strategy creation.
2626
*
2727
* @author Mark Paluch
28+
* @author Mikhail Polivakha
2829
* @since 3.2
2930
*/
3031
public class DataAccessStrategyFactory {
@@ -34,6 +35,7 @@ public class DataAccessStrategyFactory {
3435
private final NamedParameterJdbcOperations operations;
3536
private final SqlParametersFactory sqlParametersFactory;
3637
private final InsertStrategyFactory insertStrategyFactory;
38+
private final QueryMappingConfiguration queryMappingConfiguration;
3739

3840
/**
3941
* Creates a new {@link DataAccessStrategyFactory}.
@@ -46,7 +48,7 @@ public class DataAccessStrategyFactory {
4648
*/
4749
public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConverter converter,
4850
NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
49-
InsertStrategyFactory insertStrategyFactory) {
51+
InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {
5052

5153
Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
5254
Assert.notNull(converter, "JdbcConverter must not be null");
@@ -59,6 +61,7 @@ public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConv
5961
this.operations = operations;
6062
this.sqlParametersFactory = sqlParametersFactory;
6163
this.insertStrategyFactory = insertStrategyFactory;
64+
this.queryMappingConfiguration = queryMappingConfiguration;
6265
}
6366

6467
/**
@@ -70,7 +73,7 @@ public DataAccessStrategy create() {
7073

7174
DefaultDataAccessStrategy defaultDataAccessStrategy = new DefaultDataAccessStrategy(sqlGeneratorSource,
7275
this.converter.getMappingContext(), this.converter, this.operations, sqlParametersFactory,
73-
insertStrategyFactory);
76+
insertStrategyFactory, queryMappingConfiguration);
7477

7578
if (this.converter.getMappingContext().isSingleQueryLoadingEnabled()) {
7679
return new SingleQueryFallbackDataAccessStrategy(sqlGeneratorSource, converter, operations,

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java

+21-10
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
* @author Radim Tlusty
6161
* @author Chirag Tailor
6262
* @author Diego Krupitza
63+
* @author Mikhail Polivakha
6364
* @since 1.1
6465
*/
6566
public class DefaultDataAccessStrategy implements DataAccessStrategy {
@@ -71,6 +72,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
7172
private final SqlParametersFactory sqlParametersFactory;
7273
private final InsertStrategyFactory insertStrategyFactory;
7374

75+
private final QueryMappingConfiguration queryMappingConfiguration;
76+
7477
/**
7578
* Creates a {@link DefaultDataAccessStrategy}
7679
*
@@ -82,21 +85,23 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
8285
*/
8386
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
8487
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
85-
InsertStrategyFactory insertStrategyFactory) {
88+
InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {
8689

8790
Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
8891
Assert.notNull(context, "RelationalMappingContext must not be null");
8992
Assert.notNull(converter, "JdbcConverter must not be null");
9093
Assert.notNull(operations, "NamedParameterJdbcOperations must not be null");
9194
Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null");
9295
Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null");
96+
Assert.notNull(queryMappingConfiguration, "InsertStrategyFactory must not be null");
9397

9498
this.sqlGeneratorSource = sqlGeneratorSource;
9599
this.context = context;
96100
this.converter = converter;
97101
this.operations = operations;
98102
this.sqlParametersFactory = sqlParametersFactory;
99103
this.insertStrategyFactory = insertStrategyFactory;
104+
this.queryMappingConfiguration = queryMappingConfiguration;
100105
}
101106

102107
@Override
@@ -265,15 +270,15 @@ public <T> T findById(Object id, Class<T> domainType) {
265270
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
266271

267272
try {
268-
return operations.queryForObject(findOneSql, parameter, getEntityRowMapper(domainType));
273+
return operations.queryForObject(findOneSql, parameter, getRowMapper(domainType));
269274
} catch (EmptyResultDataAccessException e) {
270275
return null;
271276
}
272277
}
273278

274279
@Override
275280
public <T> List<T> findAll(Class<T> domainType) {
276-
return operations.query(sql(domainType).getFindAll(), getEntityRowMapper(domainType));
281+
return operations.query(sql(domainType).getFindAll(), getRowMapper(domainType));
277282
}
278283

279284
@Override
@@ -285,7 +290,7 @@ public <T> List<T> findAllById(Iterable<?> ids, Class<T> domainType) {
285290

286291
SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType);
287292
String findAllInListSql = sql(domainType).getFindAllInList();
288-
return operations.query(findAllInListSql, parameterSource, getEntityRowMapper(domainType));
293+
return operations.query(findAllInListSql, parameterSource, getRowMapper(domainType));
289294
}
290295

291296
@Override
@@ -339,12 +344,12 @@ public <T> boolean existsById(Object id, Class<T> domainType) {
339344

340345
@Override
341346
public <T> List<T> findAll(Class<T> domainType, Sort sort) {
342-
return operations.query(sql(domainType).getFindAll(sort), getEntityRowMapper(domainType));
347+
return operations.query(sql(domainType).getFindAll(sort), getRowMapper(domainType));
343348
}
344349

345350
@Override
346351
public <T> List<T> findAll(Class<T> domainType, Pageable pageable) {
347-
return operations.query(sql(domainType).getFindAll(pageable), getEntityRowMapper(domainType));
352+
return operations.query(sql(domainType).getFindAll(pageable), getRowMapper(domainType));
348353
}
349354

350355
@Override
@@ -354,7 +359,7 @@ public <T> Optional<T> findOne(Query query, Class<T> domainType) {
354359
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
355360

356361
try {
357-
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getEntityRowMapper(domainType)));
362+
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getRowMapper(domainType)));
358363
} catch (EmptyResultDataAccessException e) {
359364
return Optional.empty();
360365
}
@@ -366,7 +371,7 @@ public <T> List<T> findAll(Query query, Class<T> domainType) {
366371
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
367372
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
368373

369-
return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType));
374+
return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
370375
}
371376

372377
@Override
@@ -375,7 +380,7 @@ public <T> List<T> findAll(Query query, Class<T> domainType, Pageable pageable)
375380
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
376381
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource, pageable);
377382

378-
return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType));
383+
return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
379384
}
380385

381386
@Override
@@ -404,7 +409,13 @@ public <T> long count(Query query, Class<T> domainType) {
404409
return result;
405410
}
406411

407-
private <T> EntityRowMapper<T> getEntityRowMapper(Class<T> domainType) {
412+
private <T> RowMapper<? extends T> getRowMapper(Class<T> domainType) {
413+
RowMapper<? extends T> targetRowMapper;
414+
415+
if ((targetRowMapper = queryMappingConfiguration.getRowMapper(domainType)) != null) {
416+
return targetRowMapper;
417+
}
418+
408419
return new EntityRowMapper<>(getRequiredPersistentEntity(domainType), converter);
409420
}
410421

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/QueryMappingConfiguration.java spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMappingConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.springframework.data.jdbc.repository;
1+
package org.springframework.data.jdbc.core.convert;
22

33
import org.springframework.jdbc.core.RowMapper;
44
import org.springframework.lang.Nullable;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.data.domain.Pageable;
3030
import org.springframework.data.domain.Sort;
3131
import org.springframework.data.jdbc.core.convert.*;
32+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
3233
import org.springframework.data.mapping.PersistentPropertyPath;
3334
import org.springframework.data.mapping.PropertyPath;
3435
import org.springframework.data.relational.core.conversion.IdValueSource;
@@ -72,9 +73,10 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
7273
* uses a {@link DefaultDataAccessStrategy}
7374
*/
7475
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
75-
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession, Dialect dialect) {
76+
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
77+
Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {
7678
return createCombinedAccessStrategy(context, converter, operations, sqlSession, NamespaceStrategy.DEFAULT_INSTANCE,
77-
dialect);
79+
dialect, queryMappingConfiguration);
7880
}
7981

8082
/**
@@ -83,7 +85,7 @@ public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingC
8385
*/
8486
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
8587
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
86-
NamespaceStrategy namespaceStrategy, Dialect dialect) {
88+
NamespaceStrategy namespaceStrategy, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {
8789

8890
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, converter, dialect);
8991
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
@@ -94,7 +96,8 @@ public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingC
9496
converter, //
9597
operations, //
9698
sqlParametersFactory, //
97-
insertStrategyFactory //
99+
insertStrategyFactory, //
100+
queryMappingConfiguration //
98101
).create();
99102

100103
// the DefaultDataAccessStrategy needs a reference to the returned DataAccessStrategy. This creates a dependency

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
4141
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
4242
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
43+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
4344
import org.springframework.data.mapping.model.SimpleTypeHolder;
4445
import org.springframework.data.relational.RelationalManagedTypes;
4546
import org.springframework.data.relational.core.conversion.RelationalConverter;
@@ -61,6 +62,7 @@
6162
* @author Christoph Strobl
6263
* @author Myeonghyeon Lee
6364
* @author Chirag Tailor
65+
* @author Mikhail Polivakha
6466
* @since 1.1
6567
*/
6668
@Configuration(proxyBeanMethods = false)
@@ -70,6 +72,8 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {
7072

7173
private ApplicationContext applicationContext;
7274

75+
private QueryMappingConfiguration queryMappingConfiguration;
76+
7377
/**
7478
* Returns the base packages to scan for JDBC mapped entities at startup. Returns the package name of the
7579
* configuration class' (the concrete class, not this one here) by default. So if you have a
@@ -208,7 +212,9 @@ public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations op
208212
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect);
209213
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations,
210214
new SqlParametersFactory(context, jdbcConverter),
211-
new InsertStrategyFactory(operations, dialect));
215+
new InsertStrategyFactory(operations, dialect),
216+
this.queryMappingConfiguration
217+
);
212218

213219
return factory.create();
214220
}
@@ -232,6 +238,10 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
232238
this.applicationContext = applicationContext;
233239
}
234240

241+
public void setQueryMappingConfiguration(Optional<QueryMappingConfiguration> queryMappingConfiguration) throws BeansException {
242+
this.queryMappingConfiguration = queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY);
243+
}
244+
235245
/**
236246
* Scans the mapping base package for classes annotated with {@link Table}. By default, it scans for entities in all
237247
* packages returned by {@link #getMappingBasePackages()}.

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DefaultQueryMappingConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.util.LinkedHashMap;
44
import java.util.Map;
55

6-
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
6+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
77
import org.springframework.jdbc.core.ResultSetExtractor;
88
import org.springframework.jdbc.core.RowMapper;
99
import org.springframework.lang.Nullable;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.jdbc.repository.config;
1717

18+
import java.util.Optional;
19+
1820
import org.apache.ibatis.session.SqlSession;
1921
import org.springframework.beans.factory.annotation.Autowired;
2022
import org.springframework.context.annotation.Bean;
@@ -23,25 +25,29 @@
2325
import org.springframework.data.jdbc.core.convert.JdbcConverter;
2426
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
2527
import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy;
28+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
2629
import org.springframework.data.relational.core.dialect.Dialect;
2730
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
2831

2932
/**
3033
* Configuration class tweaking Spring Data JDBC to use a {@link MyBatisDataAccessStrategy} instead of the default one.
3134
*
3235
* @author Oliver Drotbohm
36+
* @author Mikhail Polivakha
3337
* @since 1.1
3438
*/
3539
@Configuration(proxyBeanMethods = false)
3640
public class MyBatisJdbcConfiguration extends AbstractJdbcConfiguration {
3741

3842
private @Autowired SqlSession session;
3943

44+
private @Autowired Optional<QueryMappingConfiguration> queryMappingConfiguration;
45+
4046
@Bean
4147
@Override
4248
public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter,
4349
JdbcMappingContext context, Dialect dialect) {
4450

45-
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect);
51+
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect, queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY));
4652
}
4753
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.springframework.context.ApplicationEventPublisher;
2626
import org.springframework.data.jdbc.core.convert.EntityRowMapper;
2727
import org.springframework.data.jdbc.core.convert.JdbcConverter;
28-
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
28+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
2929
import org.springframework.data.jdbc.repository.query.AbstractJdbcQuery;
3030
import org.springframework.data.jdbc.repository.query.JdbcQueryMethod;
3131
import org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
2323
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
2424
import org.springframework.data.jdbc.core.convert.JdbcConverter;
25-
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
25+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
2626
import org.springframework.data.mapping.callback.EntityCallbacks;
2727
import org.springframework.data.relational.core.dialect.Dialect;
2828
import org.springframework.data.relational.core.mapping.RelationalMappingContext;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.springframework.data.jdbc.core.convert.JdbcConverter;
2828
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
2929
import org.springframework.data.jdbc.core.convert.SqlParametersFactory;
30-
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
30+
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
3131
import org.springframework.data.mapping.callback.EntityCallbacks;
3232
import org.springframework.data.relational.core.dialect.Dialect;
3333
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
@@ -48,6 +48,7 @@
4848
* @author Mark Paluch
4949
* @author Hebert Coelho
5050
* @author Chirag Tailor
51+
* @author Mikhail Polivakha
5152
*/
5253
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
5354
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> implements ApplicationEventPublisherAware {
@@ -166,6 +167,10 @@ public void afterPropertiesSet() {
166167
this.operations = beanFactory.getBean(NamedParameterJdbcOperations.class);
167168
}
168169

170+
if (this.queryMappingConfiguration == null) {
171+
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
172+
}
173+
169174
if (this.dataAccessStrategy == null) {
170175

171176
Assert.state(beanFactory != null, "If no DataAccessStrategy is set a BeanFactory must be available");
@@ -181,16 +186,12 @@ public void afterPropertiesSet() {
181186
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations, this.dialect);
182187

183188
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, this.converter,
184-
this.operations, sqlParametersFactory, insertStrategyFactory);
189+
this.operations, sqlParametersFactory, insertStrategyFactory, queryMappingConfiguration);
185190

186191
return factory.create();
187192
});
188193
}
189194

190-
if (this.queryMappingConfiguration == null) {
191-
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
192-
}
193-
194195
if (beanFactory != null) {
195196
entityCallbacks = EntityCallbacks.create(beanFactory);
196197
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/DependencyTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void acrossModules() {
6262
"org.springframework.data.jdbc", // Spring Data Relational
6363
"org.springframework.data.relational", // Spring Data Relational
6464
"org.springframework.data" // Spring Data Commons
65-
).that(onlySpringData()) //
65+
)
6666
.that(ignore(AuditingHandlerBeanDefinitionParser.class)) //
6767
.that(ignorePackage("org.springframework.data.aot.hint")) // ignoring aot, since it causes cycles in commons
6868
.that(ignorePackage("org.springframework.data.aot")); // ignoring aot, since it causes cycles in commons

0 commit comments

Comments
 (0)