Browse Source

Consider QueryMappingConfiguration for part tree queries.

Signed-off-by: mipo256 <mikhailpolivakha@gmail.com>

Commit message edited by Jens Schauder

Original pull request #1893
Closes #1006
pull/2065/head
Mikhail2048 1 year ago committed by Mark Paluch
parent
commit
1d49abf0c2
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 12
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DataAccessStrategyFactory.java
  2. 39
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java
  3. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMappingConfiguration.java
  4. 11
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/mybatis/MyBatisDataAccessStrategy.java
  5. 12
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java
  6. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DefaultQueryMappingConfiguration.java
  7. 8
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java
  8. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java
  9. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java
  10. 13
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBean.java
  11. 2
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/DependencyTests.java
  12. 4
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java
  13. 4
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/mybatis/MyBatisHsqlIntegrationTests.java
  14. 122
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/PartTreeQueryMappingConfigurationIntegrationTests.java
  15. 16
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java
  16. 1
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java
  17. 2
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/ConfigurableRowMapperMapUnitTests.java
  18. 5
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java
  19. 2
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java
  20. 2
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java
  21. 5
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java
  22. 3
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-db2.sql
  23. 4
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-h2.sql
  24. 1
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-hsql.sql
  25. 1
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mariadb.sql
  26. 2
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mssql.sql
  27. 1
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mysql.sql
  28. 2
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-oracle.sql
  29. 2
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-postgres.sql

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

@ -15,7 +15,10 @@
*/ */
package org.springframework.data.jdbc.core.convert; package org.springframework.data.jdbc.core.convert;
import java.util.Optional;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -25,6 +28,7 @@ import org.springframework.util.Assert;
* {@link DataAccessStrategy} for consistent access strategy creation. * {@link DataAccessStrategy} for consistent access strategy creation.
* *
* @author Mark Paluch * @author Mark Paluch
* @author Mikhail Polivakha
* @since 3.2 * @since 3.2
*/ */
public class DataAccessStrategyFactory { public class DataAccessStrategyFactory {
@ -34,6 +38,7 @@ public class DataAccessStrategyFactory {
private final NamedParameterJdbcOperations operations; private final NamedParameterJdbcOperations operations;
private final SqlParametersFactory sqlParametersFactory; private final SqlParametersFactory sqlParametersFactory;
private final InsertStrategyFactory insertStrategyFactory; private final InsertStrategyFactory insertStrategyFactory;
private final QueryMappingConfiguration queryMappingConfiguration;
/** /**
* Creates a new {@link DataAccessStrategyFactory}. * Creates a new {@link DataAccessStrategyFactory}.
@ -43,22 +48,25 @@ public class DataAccessStrategyFactory {
* @param operations must not be {@literal null}. * @param operations must not be {@literal null}.
* @param sqlParametersFactory must not be {@literal null}. * @param sqlParametersFactory must not be {@literal null}.
* @param insertStrategyFactory must not be {@literal null}. * @param insertStrategyFactory must not be {@literal null}.
* @param queryMappingConfiguration must not be {@literal null}.
*/ */
public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConverter converter, public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConverter converter,
NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory, NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
InsertStrategyFactory insertStrategyFactory) { InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {
Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null"); Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
Assert.notNull(converter, "JdbcConverter must not be null"); Assert.notNull(converter, "JdbcConverter must not be null");
Assert.notNull(operations, "NamedParameterJdbcOperations must not be null"); Assert.notNull(operations, "NamedParameterJdbcOperations must not be null");
Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null"); Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null");
Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null"); Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null");
Assert.notNull(queryMappingConfiguration, "QueryMappingConfiguration must not be null");
this.sqlGeneratorSource = sqlGeneratorSource; this.sqlGeneratorSource = sqlGeneratorSource;
this.converter = converter; this.converter = converter;
this.operations = operations; this.operations = operations;
this.sqlParametersFactory = sqlParametersFactory; this.sqlParametersFactory = sqlParametersFactory;
this.insertStrategyFactory = insertStrategyFactory; this.insertStrategyFactory = insertStrategyFactory;
this.queryMappingConfiguration = queryMappingConfiguration;
} }
/** /**
@ -70,7 +78,7 @@ public class DataAccessStrategyFactory {
DefaultDataAccessStrategy defaultDataAccessStrategy = new DefaultDataAccessStrategy(sqlGeneratorSource, DefaultDataAccessStrategy defaultDataAccessStrategy = new DefaultDataAccessStrategy(sqlGeneratorSource,
this.converter.getMappingContext(), this.converter, this.operations, sqlParametersFactory, this.converter.getMappingContext(), this.converter, this.operations, sqlParametersFactory,
insertStrategyFactory); insertStrategyFactory, queryMappingConfiguration);
if (this.converter.getMappingContext().isSingleQueryLoadingEnabled()) { if (this.converter.getMappingContext().isSingleQueryLoadingEnabled()) {
return new SingleQueryFallbackDataAccessStrategy(sqlGeneratorSource, converter, operations, return new SingleQueryFallbackDataAccessStrategy(sqlGeneratorSource, converter, operations,

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

@ -62,6 +62,7 @@ import org.springframework.util.Assert;
* @author Chirag Tailor * @author Chirag Tailor
* @author Diego Krupitza * @author Diego Krupitza
* @author Sergey Korotaev * @author Sergey Korotaev
* @author Mikhail Polivakha
* @since 1.1 * @since 1.1
*/ */
public class DefaultDataAccessStrategy implements DataAccessStrategy { public class DefaultDataAccessStrategy implements DataAccessStrategy {
@ -73,6 +74,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
private final SqlParametersFactory sqlParametersFactory; private final SqlParametersFactory sqlParametersFactory;
private final InsertStrategyFactory insertStrategyFactory; private final InsertStrategyFactory insertStrategyFactory;
private final QueryMappingConfiguration queryMappingConfiguration;
/** /**
* Creates a {@link DefaultDataAccessStrategy} * Creates a {@link DefaultDataAccessStrategy}
* *
@ -84,7 +87,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
*/ */
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context, public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory, JdbcConverter converter, NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
InsertStrategyFactory insertStrategyFactory) { InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {
Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null"); Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
Assert.notNull(context, "RelationalMappingContext must not be null"); Assert.notNull(context, "RelationalMappingContext must not be null");
@ -92,6 +95,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
Assert.notNull(operations, "NamedParameterJdbcOperations must not be null"); Assert.notNull(operations, "NamedParameterJdbcOperations must not be null");
Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null"); Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null");
Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null"); Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null");
Assert.notNull(queryMappingConfiguration, "QueryMappingConfiguration must not be null");
this.sqlGeneratorSource = sqlGeneratorSource; this.sqlGeneratorSource = sqlGeneratorSource;
this.context = context; this.context = context;
@ -99,6 +103,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
this.operations = operations; this.operations = operations;
this.sqlParametersFactory = sqlParametersFactory; this.sqlParametersFactory = sqlParametersFactory;
this.insertStrategyFactory = insertStrategyFactory; this.insertStrategyFactory = insertStrategyFactory;
this.queryMappingConfiguration = queryMappingConfiguration;
} }
@Override @Override
@ -272,7 +277,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER); SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);
try { try {
return operations.queryForObject(findOneSql, parameter, getEntityRowMapper(domainType)); return operations.queryForObject(findOneSql, parameter, getRowMapper(domainType));
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
return null; return null;
} }
@ -280,13 +285,13 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
@Override @Override
public <T> List<T> findAll(Class<T> domainType) { public <T> List<T> findAll(Class<T> domainType) {
return operations.query(sql(domainType).getFindAll(), getEntityRowMapper(domainType)); return operations.query(sql(domainType).getFindAll(), getRowMapper(domainType));
} }
@Override @Override
public <T> Stream<T> streamAll(Class<T> domainType) { public <T> Stream<T> streamAll(Class<T> domainType) {
return operations.queryForStream(sql(domainType).getFindAll(), new MapSqlParameterSource(), return operations.queryForStream(sql(domainType).getFindAll(), new MapSqlParameterSource(),
getEntityRowMapper(domainType)); getRowMapper(domainType));
} }
@Override @Override
@ -298,7 +303,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType); SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType);
String findAllInListSql = sql(domainType).getFindAllInList(); String findAllInListSql = sql(domainType).getFindAllInList();
return operations.query(findAllInListSql, parameterSource, getEntityRowMapper(domainType)); return operations.query(findAllInListSql, parameterSource, getRowMapper(domainType));
} }
@Override @Override
@ -311,7 +316,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType); SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType);
String findAllInListSql = sql(domainType).getFindAllInList(); String findAllInListSql = sql(domainType).getFindAllInList();
return operations.queryForStream(findAllInListSql, parameterSource, getEntityRowMapper(domainType)); return operations.queryForStream(findAllInListSql, parameterSource, getRowMapper(domainType));
} }
@Override @Override
@ -365,18 +370,18 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
@Override @Override
public <T> List<T> findAll(Class<T> domainType, Sort sort) { public <T> List<T> findAll(Class<T> domainType, Sort sort) {
return operations.query(sql(domainType).getFindAll(sort), getEntityRowMapper(domainType)); return operations.query(sql(domainType).getFindAll(sort), getRowMapper(domainType));
} }
@Override @Override
public <T> Stream<T> streamAll(Class<T> domainType, Sort sort) { public <T> Stream<T> streamAll(Class<T> domainType, Sort sort) {
return operations.queryForStream(sql(domainType).getFindAll(sort), new MapSqlParameterSource(), return operations.queryForStream(sql(domainType).getFindAll(sort), new MapSqlParameterSource(),
getEntityRowMapper(domainType)); getRowMapper(domainType));
} }
@Override @Override
public <T> List<T> findAll(Class<T> domainType, Pageable pageable) { public <T> List<T> findAll(Class<T> domainType, Pageable pageable) {
return operations.query(sql(domainType).getFindAll(pageable), getEntityRowMapper(domainType)); return operations.query(sql(domainType).getFindAll(pageable), getRowMapper(domainType));
} }
@Override @Override
@ -386,7 +391,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource); String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
try { try {
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getEntityRowMapper(domainType))); return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getRowMapper(domainType)));
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
return Optional.empty(); return Optional.empty();
} }
@ -398,7 +403,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
MapSqlParameterSource parameterSource = new MapSqlParameterSource(); MapSqlParameterSource parameterSource = new MapSqlParameterSource();
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource); String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType)); return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
} }
@Override @Override
@ -407,7 +412,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
MapSqlParameterSource parameterSource = new MapSqlParameterSource(); MapSqlParameterSource parameterSource = new MapSqlParameterSource();
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource); String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
return operations.queryForStream(sqlQuery, parameterSource, getEntityRowMapper(domainType)); return operations.queryForStream(sqlQuery, parameterSource, getRowMapper(domainType));
} }
@Override @Override
@ -416,7 +421,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
MapSqlParameterSource parameterSource = new MapSqlParameterSource(); MapSqlParameterSource parameterSource = new MapSqlParameterSource();
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource, pageable); String sqlQuery = sql(domainType).selectByQuery(query, parameterSource, pageable);
return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType)); return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
} }
@Override @Override
@ -445,7 +450,13 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
return result; return result;
} }
private <T> EntityRowMapper<T> getEntityRowMapper(Class<T> domainType) { private <T> RowMapper<? extends T> getRowMapper(Class<T> domainType) {
RowMapper<? extends T> targetRowMapper;
if ((targetRowMapper = queryMappingConfiguration.getRowMapper(domainType)) != null) {
return targetRowMapper;
}
return new EntityRowMapper<>(getRequiredPersistentEntity(domainType), converter); return new EntityRowMapper<>(getRequiredPersistentEntity(domainType), converter);
} }

2
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,4 +1,4 @@
package org.springframework.data.jdbc.repository; package org.springframework.data.jdbc.core.convert;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;

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

@ -32,6 +32,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.*; import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.relational.core.conversion.IdValueSource; import org.springframework.data.relational.core.conversion.IdValueSource;
@ -76,9 +77,10 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
* uses a {@link DefaultDataAccessStrategy} * uses a {@link DefaultDataAccessStrategy}
*/ */
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context, public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession, Dialect dialect) { JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {
return createCombinedAccessStrategy(context, converter, operations, sqlSession, NamespaceStrategy.DEFAULT_INSTANCE, return createCombinedAccessStrategy(context, converter, operations, sqlSession, NamespaceStrategy.DEFAULT_INSTANCE,
dialect); dialect, queryMappingConfiguration);
} }
/** /**
@ -87,7 +89,7 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
*/ */
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context, public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession, JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
NamespaceStrategy namespaceStrategy, Dialect dialect) { NamespaceStrategy namespaceStrategy, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, converter, dialect); SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, converter, dialect);
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter); SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
@ -98,7 +100,8 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
converter, // converter, //
operations, // operations, //
sqlParametersFactory, // sqlParametersFactory, //
insertStrategyFactory // insertStrategyFactory, //
queryMappingConfiguration //
).create(); ).create();
// the DefaultDataAccessStrategy needs a reference to the returned DataAccessStrategy. This creates a dependency // the DefaultDataAccessStrategy needs a reference to the returned DataAccessStrategy. This creates a dependency

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

@ -42,6 +42,7 @@ import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns;
import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes; import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.RelationalManagedTypes; import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.conversion.RelationalConverter; import org.springframework.data.relational.core.conversion.RelationalConverter;
@ -63,6 +64,7 @@ import org.springframework.util.StringUtils;
* @author Christoph Strobl * @author Christoph Strobl
* @author Myeonghyeon Lee * @author Myeonghyeon Lee
* @author Chirag Tailor * @author Chirag Tailor
* @author Mikhail Polivakha
* @since 1.1 * @since 1.1
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ -72,6 +74,8 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private QueryMappingConfiguration queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
/** /**
* Returns the base packages to scan for JDBC mapped entities at startup. Returns the package name of the * Returns the base packages to scan for JDBC mapped entities at startup. Returns the package name of the
* configuration class' (the concrete class, not this one here) by default. So if you have a * configuration class' (the concrete class, not this one here) by default. So if you have a
@ -224,7 +228,9 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect); SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect);
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations, DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations,
new SqlParametersFactory(context, jdbcConverter), new InsertStrategyFactory(operations, dialect)); new SqlParametersFactory(context, jdbcConverter), new InsertStrategyFactory(operations, dialect),
this.queryMappingConfiguration
);
return factory.create(); return factory.create();
} }
@ -248,6 +254,10 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }
public void setQueryMappingConfiguration(Optional<QueryMappingConfiguration> queryMappingConfiguration) throws BeansException {
this.queryMappingConfiguration = queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY);
}
/** /**
* Scans the mapping base package for classes annotated with {@link Table}. By default, it scans for entities in all * Scans the mapping base package for classes annotated with {@link Table}. By default, it scans for entities in all
* packages returned by {@link #getMappingBasePackages()}. * packages returned by {@link #getMappingBasePackages()}.

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

@ -3,7 +3,7 @@ package org.springframework.data.jdbc.repository.config;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;

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

@ -15,6 +15,8 @@
*/ */
package org.springframework.data.jdbc.repository.config; package org.springframework.data.jdbc.repository.config;
import java.util.Optional;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -23,6 +25,7 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy; import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
@ -30,6 +33,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
* Configuration class tweaking Spring Data JDBC to use a {@link MyBatisDataAccessStrategy} instead of the default one. * Configuration class tweaking Spring Data JDBC to use a {@link MyBatisDataAccessStrategy} instead of the default one.
* *
* @author Oliver Drotbohm * @author Oliver Drotbohm
* @author Mikhail Polivakha
* @since 1.1 * @since 1.1
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ -37,11 +41,13 @@ public class MyBatisJdbcConfiguration extends AbstractJdbcConfiguration {
private @Autowired SqlSession session; private @Autowired SqlSession session;
private @Autowired Optional<QueryMappingConfiguration> queryMappingConfiguration;
@Bean @Bean
@Override @Override
public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter, public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter,
JdbcMappingContext context, Dialect dialect) { JdbcMappingContext context, Dialect dialect) {
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect); return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect, queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY));
} }
} }

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

@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.query.DefaultRowMapperFactory; import org.springframework.data.jdbc.repository.query.DefaultRowMapperFactory;
import org.springframework.data.jdbc.repository.query.JdbcQueryMethod; import org.springframework.data.jdbc.repository.query.JdbcQueryMethod;
import org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery; import org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery;

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

@ -22,7 +22,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate; import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalMappingContext;

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

@ -27,7 +27,7 @@ import org.springframework.data.jdbc.core.convert.InsertStrategyFactory;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource; import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
import org.springframework.data.jdbc.core.convert.SqlParametersFactory; import org.springframework.data.jdbc.core.convert.SqlParametersFactory;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalMappingContext;
@ -48,6 +48,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch * @author Mark Paluch
* @author Hebert Coelho * @author Hebert Coelho
* @author Chirag Tailor * @author Chirag Tailor
* @author Mikhail Polivakha
*/ */
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> implements ApplicationEventPublisherAware { extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> implements ApplicationEventPublisherAware {
@ -166,6 +167,10 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
this.operations = beanFactory.getBean(NamedParameterJdbcOperations.class); this.operations = beanFactory.getBean(NamedParameterJdbcOperations.class);
} }
if (this.queryMappingConfiguration == null) {
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
}
if (this.dataAccessStrategy == null) { if (this.dataAccessStrategy == null) {
Assert.state(beanFactory != null, "If no DataAccessStrategy is set a BeanFactory must be available"); Assert.state(beanFactory != null, "If no DataAccessStrategy is set a BeanFactory must be available");
@ -181,16 +186,12 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations, this.dialect); InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations, this.dialect);
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, this.converter, DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, this.converter,
this.operations, sqlParametersFactory, insertStrategyFactory); this.operations, sqlParametersFactory, insertStrategyFactory, queryMappingConfiguration);
return factory.create(); return factory.create();
}); });
} }
if (this.queryMappingConfiguration == null) {
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
}
if (beanFactory != null) { if (beanFactory != null) {
entityCallbacks = EntityCallbacks.create(beanFactory); entityCallbacks = EntityCallbacks.create(beanFactory);
} }

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

@ -64,7 +64,7 @@ public class DependencyTests {
"org.springframework.data.jdbc", // Spring Data Relational "org.springframework.data.jdbc", // Spring Data Relational
"org.springframework.data.relational", // Spring Data Relational "org.springframework.data.relational", // Spring Data Relational
"org.springframework.data" // Spring Data Commons "org.springframework.data" // Spring Data Commons
).that(onlySpringData()) // )
.that(ignore(AuditingHandlerBeanDefinitionParser.class)) // .that(ignore(AuditingHandlerBeanDefinitionParser.class)) //
.that(ignorePackage("org.springframework.data.aot.hint")) // ignoring aot, since it causes cycles in commons .that(ignorePackage("org.springframework.data.aot.hint")) // ignoring aot, since it causes cycles in commons
.that(ignorePackage("org.springframework.data.aot")); // ignoring aot, since it causes cycles in commons .that(ignorePackage("org.springframework.data.aot")); // ignoring aot, since it causes cycles in commons

4
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java

@ -40,6 +40,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
* @author Myat Min * @author Myat Min
* @author Radim Tlusty * @author Radim Tlusty
* @author Chirag Tailor * @author Chirag Tailor
* @author Mikhail Polivakha
*/ */
class DefaultDataAccessStrategyUnitTests { class DefaultDataAccessStrategyUnitTests {
@ -66,7 +67,8 @@ class DefaultDataAccessStrategyUnitTests {
converter, // converter, //
namedJdbcOperations, // namedJdbcOperations, //
sqlParametersFactory, // sqlParametersFactory, //
insertStrategyFactory).create(); insertStrategyFactory,
QueryMappingConfiguration.EMPTY).create();
relationResolver.setDelegate(accessStrategy); relationResolver.setDelegate(accessStrategy);

4
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/mybatis/MyBatisHsqlIntegrationTests.java

@ -30,6 +30,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.dialect.JdbcHsqlDbDialect; import org.springframework.data.jdbc.core.dialect.JdbcHsqlDbDialect;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.testing.DatabaseType; import org.springframework.data.jdbc.testing.DatabaseType;
import org.springframework.data.jdbc.testing.EnabledOnDatabase; import org.springframework.data.jdbc.testing.EnabledOnDatabase;
@ -49,6 +50,7 @@ import junit.framework.AssertionFailedError;
* @author Jens Schauder * @author Jens Schauder
* @author Greg Turnquist * @author Greg Turnquist
* @author Mark Paluch * @author Mark Paluch
* @author Mikhail Polivakha
*/ */
@IntegrationTest @IntegrationTest
@EnabledOnDatabase(DatabaseType.HSQL) @EnabledOnDatabase(DatabaseType.HSQL)
@ -119,7 +121,7 @@ public class MyBatisHsqlIntegrationTests {
SqlSession sqlSession, EmbeddedDatabase db) { SqlSession sqlSession, EmbeddedDatabase db) {
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, converter, return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, converter,
new NamedParameterJdbcTemplate(db), sqlSession, JdbcHsqlDbDialect.INSTANCE); new NamedParameterJdbcTemplate(db), sqlSession, JdbcHsqlDbDialect.INSTANCE, QueryMappingConfiguration.EMPTY);
} }
} }
} }

122
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/PartTreeQueryMappingConfigurationIntegrationTests.java

@ -0,0 +1,122 @@
package org.springframework.data.jdbc.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.query.PartTreeJdbcQuery;
import org.springframework.data.jdbc.testing.IntegrationTest;
import org.springframework.data.jdbc.testing.TestConfiguration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.jdbc.core.RowMapper;
/**
* Tests for mapping the results of {@link PartTreeJdbcQuery} execution via custom {@link QueryMappingConfiguration}
*
* @author Mikhail Polivakha
*/
@IntegrationTest
public class PartTreeQueryMappingConfigurationIntegrationTests {
@Configuration
@Import(TestConfiguration.class)
@EnableJdbcRepositories(
considerNestedRepositories = true,
includeFilters = @ComponentScan.Filter(value = CarRepository.class, type = FilterType.ASSIGNABLE_TYPE))
static class Config {
@Bean
QueryMappingConfiguration mappers(@Qualifier("CustomRowMapperBean") CustomRowMapperBean rowMapperBean) {
return new DefaultQueryMappingConfiguration().registerRowMapper(Car.class, rowMapperBean);
}
@Bean(value = "CustomRowMapperBean")
public CustomRowMapperBean rowMapperBean() {
return new CustomRowMapperBean();
}
}
@Autowired
private CarRepository carRepository;
@Test // DATAJDBC-1006
void testCustomQueryMappingConfiguration_predefinedPartTreeQuery() {
// given
Car saved = carRepository.save(new Car(null, "test-model"));
// when
Optional<Car> found = carRepository.findById(saved.getId());
// then
Assertions.assertThat(found).isPresent().hasValueSatisfying(car -> Assertions.assertThat(car.getModel()).isEqualTo("STUB"));
}
@Test // DATAJDBC-1006
void testCustomQueryMappingConfiguration_customPartTreeQuery() {
// given
Car saved = carRepository.save(new Car(null, "test-model"));
// when
Optional<Car> found = carRepository.findOneByModel("test-model");
// then
Assertions.assertThat(found).isPresent().hasValueSatisfying(car -> Assertions.assertThat(car.getModel()).isEqualTo("STUB"));
}
public static class CustomRowMapperBean implements RowMapper<Car> {
@Override
public Car mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Car(rs.getLong("id"), "STUB");
}
}
interface CarRepository extends CrudRepository<Car, Long> {
Optional<Car> findOneByModel(String model);
}
public static class Car {
@Id
private Long id;
private String model;
public Car(Long id, String model) {
this.id = id;
this.model = model;
}
public Long getId() {
return this.id;
}
public String getModel() {
return this.model;
}
public void setId(Long id) {
this.id = id;
}
public void setModel(String model) {
this.model = model;
}
}
}

16
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java

@ -38,17 +38,8 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.core.convert.DefaultJdbcTypeFactory; import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.convert.DelegatingDataAccessStrategy;
import org.springframework.data.jdbc.core.convert.InsertStrategyFactory;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
import org.springframework.data.jdbc.core.convert.SqlParametersFactory;
import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect;
import org.springframework.data.jdbc.core.dialect.JdbcHsqlDbDialect;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository; import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository;
@ -83,6 +74,7 @@ import org.springframework.util.ObjectUtils;
* @author Milan Milanov * @author Milan Milanov
* @author Myeonghyeon Lee * @author Myeonghyeon Lee
* @author Chirag Tailor * @author Chirag Tailor
* @author Mikhail Polivakha
*/ */
class SimpleJdbcRepositoryEventsUnitTests { class SimpleJdbcRepositoryEventsUnitTests {
@ -108,7 +100,7 @@ class SimpleJdbcRepositoryEventsUnitTests {
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations, dialect); InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations, dialect);
this.dataAccessStrategy = spy(new DefaultDataAccessStrategy(generatorSource, context, converter, operations, this.dataAccessStrategy = spy(new DefaultDataAccessStrategy(generatorSource, context, converter, operations,
sqlParametersFactory, insertStrategyFactory)); sqlParametersFactory, insertStrategyFactory, QueryMappingConfiguration.EMPTY));
delegatingDataAccessStrategy.setDelegate(dataAccessStrategy); delegatingDataAccessStrategy.setDelegate(dataAccessStrategy);
doReturn(true).when(dataAccessStrategy).update(any(), any()); doReturn(true).when(dataAccessStrategy).update(any(), any());

1
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/StringBasedJdbcQueryMappingConfigurationIntegrationTests.java

@ -31,6 +31,7 @@ import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration; import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.query.Query;

2
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/ConfigurableRowMapperMapUnitTests.java

@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
/** /**

5
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcRepositoriesIntegrationTests.java

@ -40,7 +40,7 @@ import org.springframework.data.jdbc.core.convert.InsertStrategyFactory;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource; import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
import org.springframework.data.jdbc.core.convert.SqlParametersFactory; import org.springframework.data.jdbc.core.convert.SqlParametersFactory;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean;
import org.springframework.data.jdbc.testing.IntegrationTest; import org.springframework.data.jdbc.testing.IntegrationTest;
import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.jdbc.testing.TestConfiguration;
@ -62,6 +62,7 @@ import org.springframework.util.ReflectionUtils;
* @author Fei Dong * @author Fei Dong
* @author Chirag Tailor * @author Chirag Tailor
* @author Diego Krupitza * @author Diego Krupitza
* @author Mikhail Polivakha
*/ */
@IntegrationTest @IntegrationTest
public class EnableJdbcRepositoriesIntegrationTests { public class EnableJdbcRepositoriesIntegrationTests {
@ -168,7 +169,7 @@ public class EnableJdbcRepositoriesIntegrationTests {
RelationalMappingContext context, JdbcConverter converter, Dialect dialect) { RelationalMappingContext context, JdbcConverter converter, Dialect dialect) {
return new DataAccessStrategyFactory(new SqlGeneratorSource(context, converter, dialect), converter, template, return new DataAccessStrategyFactory(new SqlGeneratorSource(context, converter, dialect), converter, template,
new SqlParametersFactory(context, converter), new SqlParametersFactory(context, converter),
new InsertStrategyFactory(template, dialect)).create(); new InsertStrategyFactory(template, dialect), QueryMappingConfiguration.EMPTY).create();
} }
@Bean @Bean

2
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategyUnitTests.java

@ -31,7 +31,7 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect; import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration; import org.springframework.data.jdbc.repository.config.DefaultQueryMappingConfiguration;
import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.mapping.callback.EntityCallbacks;

2
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java

@ -38,7 +38,7 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy; import org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy;
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter; import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;

5
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java

@ -41,6 +41,7 @@ import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns;
import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes; import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration;
import org.springframework.data.jdbc.repository.config.DialectResolver; import org.springframework.data.jdbc.repository.config.DialectResolver;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.data.mapping.callback.EntityCallback;
@ -118,10 +119,10 @@ public class TestConfiguration {
@Bean @Bean
DataAccessStrategy defaultDataAccessStrategy( DataAccessStrategy defaultDataAccessStrategy(
@Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, RelationalMappingContext context, @Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, RelationalMappingContext context,
JdbcConverter converter, Dialect dialect) { JdbcConverter converter, Dialect dialect, Optional<QueryMappingConfiguration> queryMappingConfiguration) {
return new DataAccessStrategyFactory(new SqlGeneratorSource(context, converter, dialect), converter, template, return new DataAccessStrategyFactory(new SqlGeneratorSource(context, converter, dialect), converter, template,
new SqlParametersFactory(context, converter), new InsertStrategyFactory(template, dialect)).create(); new SqlParametersFactory(context, converter), new InsertStrategyFactory(template, dialect), queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY)).create();
} }
@Bean("jdbcMappingContext") @Bean("jdbcMappingContext")

3
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-db2.sql

@ -0,0 +1,3 @@
DROP TABLE car;
CREATE TABLE car ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, model VARCHAR(100));

4
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-h2.sql

@ -0,0 +1,4 @@
DROP TABLE car;
CREATE TABLE car ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, model VARCHAR(100));

1
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-hsql.sql

@ -0,0 +1 @@
CREATE TABLE car ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, model VARCHAR(100));

1
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mariadb.sql

@ -0,0 +1 @@
CREATE TABLE car ( id INT NOT NULL AUTO_INCREMENT, model VARCHAR(100), PRIMARY KEY (id));

2
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mssql.sql

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS car;
CREATE TABLE car ( id int IDENTITY(1,1) PRIMARY KEY, model VARCHAR(100));

1
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-mysql.sql

@ -0,0 +1 @@
CREATE TABLE car ( id INT NOT NULL AUTO_INCREMENT, model VARCHAR(100), PRIMARY KEY (id));

2
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-oracle.sql

@ -0,0 +1,2 @@
DROP TABLE CAR;
CREATE TABLE CAR ( id NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY, model VARCHAR(100));

2
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/PartTreeQueryMappingConfigurationIntegrationTests-postgres.sql

@ -0,0 +1,2 @@
DROP TABLE car;
CREATE TABLE car ( id SERIAL PRIMARY KEY, model VARCHAR(100));
Loading…
Cancel
Save