Skip to content

Commit aaae9a5

Browse files
schauderchristophstrobl
authored andcommitted
DATAJDBC-155 - Simplified construction of JdbcRepositoryFactory.
Made the DefaultDataAccessStrategy actually the default for JdbcRepositoryFactoryBean. Therefore the injection of a strategy is optional. Simplified constructors of DefaultDataAccessStrategy. Created factory method to construct a correct DataAccessStrategy for use with MyBatis. Did some untangling in the test application context configurations. Original pull request: #54.
1 parent ce020a4 commit aaae9a5

File tree

8 files changed

+75
-44
lines changed

8 files changed

+75
-44
lines changed

src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
5656
private final JdbcMappingContext context;
5757
private final DataAccessStrategy accessStrategy;
5858

59-
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, NamedParameterJdbcOperations operations,
60-
JdbcMappingContext context, DataAccessStrategy accessStrategy) {
59+
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, JdbcMappingContext context,
60+
DataAccessStrategy accessStrategy) {
6161

6262
this.sqlGeneratorSource = sqlGeneratorSource;
63-
this.operations = operations;
63+
this.operations = context.getTemplate();
6464
this.context = context;
6565
this.accessStrategy = accessStrategy;
6666
}
@@ -69,11 +69,10 @@ public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, NamedPar
6969
* Creates a {@link DefaultDataAccessStrategy} which references it self for resolution of recursive data accesses.
7070
* Only suitable if this is the only access strategy in use.
7171
*/
72-
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, NamedParameterJdbcOperations operations,
73-
JdbcMappingContext context) {
72+
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, JdbcMappingContext context) {
7473

7574
this.sqlGeneratorSource = sqlGeneratorSource;
76-
this.operations = operations;
75+
this.operations = context.getTemplate();
7776
this.context = context;
7877
this.accessStrategy = this;
7978
}

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

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,22 @@
1515
*/
1616
package org.springframework.data.jdbc.mybatis;
1717

18+
import static java.util.Arrays.*;
19+
20+
import java.util.Collections;
21+
import java.util.Map;
22+
1823
import org.apache.ibatis.session.SqlSession;
1924
import org.mybatis.spring.SqlSessionTemplate;
25+
import org.springframework.data.jdbc.core.CascadingDataAccessStrategy;
2026
import org.springframework.data.jdbc.core.DataAccessStrategy;
27+
import org.springframework.data.jdbc.core.DefaultDataAccessStrategy;
28+
import org.springframework.data.jdbc.core.DelegatingDataAccessStrategy;
29+
import org.springframework.data.jdbc.core.SqlGeneratorSource;
30+
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
2131
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
2232
import org.springframework.data.mapping.PropertyPath;
2333

24-
import java.util.Collections;
25-
import java.util.Map;
26-
2734
/**
2835
* {@link DataAccessStrategy} implementation based on MyBatis. Each method gets mapped to a statement. The name of the
2936
* statement gets constructed as follows: The namespace is based on the class of the entity plus the suffix "Mapper".
@@ -41,11 +48,43 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
4148

4249
private final SqlSession sqlSession;
4350

51+
/**
52+
* Create a {@link DataAccessStrategy} that first checks for queries defined by MyBatis and if it doesn't find one
53+
* used a {@link DefaultDataAccessStrategy}
54+
*
55+
* @param context
56+
* @param sqlSession
57+
* @return
58+
*/
59+
public static DataAccessStrategy createCombinedAccessStrategy(JdbcMappingContext context, SqlSession sqlSession) {
60+
61+
// the DefaultDataAccessStrategy needs a reference to the returned DataAccessStrategy. This creates a dependency
62+
// cycle. In order to create it, we need something that allows to defer closing the cycle until all the elements are
63+
// created. That is the purpose of the DelegatingAccessStrategy.
64+
DelegatingDataAccessStrategy delegatingDataAccessStrategy = new DelegatingDataAccessStrategy();
65+
MyBatisDataAccessStrategy myBatisDataAccessStrategy = new MyBatisDataAccessStrategy(sqlSession);
66+
67+
CascadingDataAccessStrategy cascadingDataAccessStrategy = new CascadingDataAccessStrategy(
68+
asList(myBatisDataAccessStrategy, delegatingDataAccessStrategy));
69+
70+
DefaultDataAccessStrategy defaultDataAccessStrategy = new DefaultDataAccessStrategy( //
71+
new SqlGeneratorSource(context), //
72+
context, //
73+
cascadingDataAccessStrategy);
74+
75+
delegatingDataAccessStrategy.setDelegate(defaultDataAccessStrategy);
76+
77+
return cascadingDataAccessStrategy;
78+
}
79+
4480
/**
4581
* Constructs a {@link DataAccessStrategy} based on MyBatis.
4682
* <p>
47-
* Use a {@link SqlSessionTemplate} for {@link SqlSession} or a similar implementation tying the session to the
48-
* proper transaction.
83+
* Use a {@link SqlSessionTemplate} for {@link SqlSession} or a similar implementation tying the session to the proper
84+
* transaction. Note that the resulting {@link DataAccessStrategy} only handles MyBatis. It does not include the
85+
* functionality of the {@link org.springframework.data.jdbc.core.DefaultDataAccessStrategy} which one normally still
86+
* wants. Use {@link #createCombinedAccessStrategy(JdbcMappingContext, SqlSession)} to create such a
87+
* {@link DataAccessStrategy}.
4988
*
5089
* @param sqlSession Must be non {@literal null}.
5190
*/

src/main/java/org/springframework/data/jdbc/repository/config/JdbcConfiguration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@
2222
import org.springframework.data.jdbc.mapping.model.ConversionCustomizer;
2323
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
2424
import org.springframework.data.jdbc.mapping.model.NamingStrategy;
25+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
2526
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
2627

2728
/**
2829
* Beans that must be registered for Spring Data JDBC to work.
2930
*
3031
* @author Greg Turnquist
32+
* @author Jens Schauder
3133
*/
3234
@Configuration
3335
public class JdbcConfiguration {
3436

3537
@Bean
36-
JdbcMappingContext jdbcMappingContext(NamedParameterJdbcTemplate template, Optional<NamingStrategy> namingStrategy,
38+
JdbcMappingContext jdbcMappingContext(NamedParameterJdbcOperations template, Optional<NamingStrategy> namingStrategy,
3739
Optional<ConversionCustomizer> conversionCustomizer) {
3840

3941
return new JdbcMappingContext(namingStrategy.orElse(NamingStrategy.INSTANCE), template,

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.context.ApplicationEventPublisher;
2222
import org.springframework.context.ApplicationEventPublisherAware;
2323
import org.springframework.data.jdbc.core.DataAccessStrategy;
24+
import org.springframework.data.jdbc.core.DefaultDataAccessStrategy;
25+
import org.springframework.data.jdbc.core.SqlGeneratorSource;
2426
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
2527
import org.springframework.data.jdbc.repository.RowMapperMap;
2628
import org.springframework.data.repository.Repository;
@@ -80,7 +82,7 @@ protected void setMappingContext(JdbcMappingContext mappingContext) {
8082
this.mappingContext = mappingContext;
8183
}
8284

83-
@Autowired
85+
@Autowired(required = false)
8486
public void setDataAccessStrategy(DataAccessStrategy dataAccessStrategy) {
8587
this.dataAccessStrategy = dataAccessStrategy;
8688
}
@@ -93,8 +95,15 @@ public void setRowMapperMap(RowMapperMap rowMapperMap) {
9395
@Override
9496
public void afterPropertiesSet() {
9597

96-
Assert.notNull(this.dataAccessStrategy, "DataAccessStrategy must not be null!");
9798
Assert.notNull(this.mappingContext, "MappingContext must not be null!");
99+
100+
if (dataAccessStrategy == null) {
101+
102+
dataAccessStrategy = new DefaultDataAccessStrategy( //
103+
new SqlGeneratorSource(mappingContext), //
104+
mappingContext);
105+
}
106+
98107
super.afterPropertiesSet();
99108
}
100109
}

src/test/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategyUnitTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public class DefaultDataAccessStrategyUnitTests {
4848

4949
DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( //
5050
new SqlGeneratorSource(context), //
51-
jdbcOperations, //
5251
context //
5352
);
5453

src/test/java/org/springframework/data/jdbc/mybatis/MyBatisHsqlIntegrationTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.data.jdbc.mybatis;
1717

18-
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.*;
1919

2020
import junit.framework.AssertionFailedError;
2121

@@ -30,6 +30,8 @@
3030
import org.springframework.beans.factory.annotation.Autowired;
3131
import org.springframework.context.annotation.Bean;
3232
import org.springframework.context.annotation.Import;
33+
import org.springframework.data.jdbc.core.DataAccessStrategy;
34+
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
3335
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
3436
import org.springframework.data.jdbc.testing.TestConfiguration;
3537
import org.springframework.data.repository.CrudRepository;
@@ -39,8 +41,6 @@
3941
import org.springframework.test.context.junit4.rules.SpringMethodRule;
4042
import org.springframework.transaction.annotation.Transactional;
4143

42-
import javax.net.ssl.SSLSocketFactory;
43-
4444
/**
4545
* Tests the integration with Mybatis.
4646
*
@@ -83,8 +83,8 @@ SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory factory) {
8383
}
8484

8585
@Bean
86-
MyBatisDataAccessStrategy dataAccessStrategy(SqlSession sqlSession) {
87-
return new MyBatisDataAccessStrategy(sqlSession);
86+
DataAccessStrategy dataAccessStrategy(JdbcMappingContext context, SqlSession sqlSession) {
87+
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, sqlSession);
8888
}
8989
}
9090

src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,12 @@ public class SimpleJdbcRepositoryEventsUnitTests {
4646
@Before
4747
public void before() {
4848

49-
final JdbcMappingContext context = new JdbcMappingContext(mock(NamedParameterJdbcOperations.class));
49+
final JdbcMappingContext context = new JdbcMappingContext(createIdGeneratingOperations());
5050
JdbcRepositoryFactory factory = new JdbcRepositoryFactory( //
5151
publisher, //
5252
context, //
5353
new DefaultDataAccessStrategy( //
5454
new SqlGeneratorSource(context), //
55-
createIdGeneratingOperations(), //
5655
context //
5756
) //
5857
);

src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@
2121

2222
import org.apache.ibatis.session.SqlSessionFactory;
2323
import org.springframework.beans.factory.annotation.Autowired;
24-
import org.springframework.beans.factory.annotation.Qualifier;
2524
import org.springframework.context.ApplicationEventPublisher;
2625
import org.springframework.context.annotation.Bean;
2726
import org.springframework.context.annotation.ComponentScan;
2827
import org.springframework.context.annotation.Configuration;
2928
import org.springframework.data.jdbc.core.DataAccessStrategy;
3029
import org.springframework.data.jdbc.core.DefaultDataAccessStrategy;
31-
import org.springframework.data.jdbc.core.DelegatingDataAccessStrategy;
3230
import org.springframework.data.jdbc.core.SqlGeneratorSource;
3331
import org.springframework.data.jdbc.mapping.model.ConversionCustomizer;
3432
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
@@ -54,24 +52,21 @@ public class TestConfiguration {
5452
@Autowired(required = false) SqlSessionFactory sqlSessionFactory;
5553

5654
@Bean
57-
JdbcRepositoryFactory jdbcRepositoryFactory() {
55+
JdbcRepositoryFactory jdbcRepositoryFactory(DataAccessStrategy dataAccessStrategy) {
5856

59-
NamedParameterJdbcTemplate jdbcTemplate = namedParameterJdbcTemplate();
57+
NamedParameterJdbcOperations jdbcTemplate = namedParameterJdbcTemplate();
6058

6159
final JdbcMappingContext context = new JdbcMappingContext(NamingStrategy.INSTANCE, jdbcTemplate, __ -> {});
6260

6361
return new JdbcRepositoryFactory( //
6462
publisher, //
6563
context, //
66-
new DefaultDataAccessStrategy( //
67-
new SqlGeneratorSource(context), //
68-
jdbcTemplate, //
69-
context) //
64+
dataAccessStrategy //
7065
);
7166
}
7267

7368
@Bean
74-
NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
69+
NamedParameterJdbcOperations namedParameterJdbcTemplate() {
7570
return new NamedParameterJdbcTemplate(dataSource);
7671
}
7772

@@ -81,19 +76,8 @@ PlatformTransactionManager transactionManager() {
8176
}
8277

8378
@Bean
84-
DataAccessStrategy defaultDataAccessStrategy(JdbcMappingContext context,
85-
@Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations operations) {
86-
87-
DelegatingDataAccessStrategy accessStrategy = new DelegatingDataAccessStrategy();
88-
89-
accessStrategy.setDelegate(new DefaultDataAccessStrategy( //
90-
new SqlGeneratorSource(context), //
91-
operations, //
92-
context, //
93-
accessStrategy) //
94-
);
95-
96-
return accessStrategy;
79+
DataAccessStrategy defaultDataAccessStrategy(JdbcMappingContext context) {
80+
return new DefaultDataAccessStrategy(new SqlGeneratorSource(context), context);
9781
}
9882

9983
@Bean

0 commit comments

Comments
 (0)