Skip to content

Commit b4002e5

Browse files
committed
#440 - Create R2dbcEntityTemplate in R2dbcRepositoryFactoryBean.
We now create R2dbcEntityTemplate as part of R2dbcRepositoryFactoryBean initialization if the factory bean was configured with DatabaseClient and DataAccessStrategy only. Creating the template in the factory bean allows collecting entity callbacks for repository usage.
1 parent dc8eb79 commit b4002e5

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
6060
private final ReactiveDataAccessStrategy dataAccessStrategy;
6161
private final MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> mappingContext;
6262
private final R2dbcConverter converter;
63+
private final R2dbcEntityOperations operations;
6364

6465
/**
6566
* Creates a new {@link R2dbcRepositoryFactory} given {@link DatabaseClient} and {@link MappingContext}.
@@ -76,6 +77,7 @@ public R2dbcRepositoryFactory(DatabaseClient databaseClient, ReactiveDataAccessS
7677
this.dataAccessStrategy = dataAccessStrategy;
7778
this.converter = dataAccessStrategy.getConverter();
7879
this.mappingContext = this.converter.getMappingContext();
80+
this.operations = new R2dbcEntityTemplate(this.databaseClient, this.dataAccessStrategy);
7981
setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
8082
}
8183

@@ -93,6 +95,7 @@ public R2dbcRepositoryFactory(R2dbcEntityOperations operations) {
9395
this.dataAccessStrategy = operations.getDataAccessStrategy();
9496
this.converter = dataAccessStrategy.getConverter();
9597
this.mappingContext = this.converter.getMappingContext();
98+
this.operations = operations;
9699
setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
97100
}
98101

@@ -116,7 +119,7 @@ protected Object getTargetRepository(RepositoryInformation information) {
116119
information);
117120

118121
return getTargetRepositoryViaReflection(information, entityInformation,
119-
new R2dbcEntityTemplate(this.databaseClient, this.dataAccessStrategy), this.converter);
122+
operations, this.converter);
120123
}
121124

122125
/*

src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
import java.io.Serializable;
1919

20+
import org.springframework.beans.BeansException;
21+
import org.springframework.context.ApplicationContext;
22+
import org.springframework.context.ApplicationContextAware;
2023
import org.springframework.data.mapping.context.MappingContext;
2124
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
25+
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
2226
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
2327
import org.springframework.data.repository.Repository;
2428
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
@@ -38,11 +42,12 @@
3842
* @see org.springframework.data.repository.reactive.ReactiveSortingRepository
3943
*/
4044
public class R2dbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
41-
extends RepositoryFactoryBeanSupport<T, S, ID> {
45+
extends RepositoryFactoryBeanSupport<T, S, ID> implements ApplicationContextAware {
4246

4347
private @Nullable DatabaseClient client;
4448
private @Nullable ReactiveDataAccessStrategy dataAccessStrategy;
4549
private @Nullable R2dbcEntityOperations operations;
50+
private @Nullable ApplicationContext applicationContext;
4651

4752
private boolean mappingContextConfigured = false;
4853

@@ -122,6 +127,15 @@ protected RepositoryFactorySupport getFactoryInstance(R2dbcEntityOperations oper
122127
return new R2dbcRepositoryFactory(operations);
123128
}
124129

130+
/*
131+
* (non-Javadoc)
132+
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
133+
*/
134+
@Override
135+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
136+
this.applicationContext = applicationContext;
137+
}
138+
125139
/*
126140
* (non-Javadoc)
127141
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
@@ -134,6 +148,14 @@ public void afterPropertiesSet() {
134148
Assert.state(client != null, "DatabaseClient must not be null when R2dbcEntityOperations is not configured!");
135149
Assert.state(dataAccessStrategy != null,
136150
"ReactiveDataAccessStrategy must not be null when R2dbcEntityOperations is not configured!");
151+
152+
R2dbcEntityTemplate template = new R2dbcEntityTemplate(client, dataAccessStrategy);
153+
154+
if (applicationContext != null) {
155+
template.setApplicationContext(applicationContext);
156+
}
157+
158+
operations = template;
137159
} else {
138160
dataAccessStrategy = operations.getDataAccessStrategy();
139161
}

src/test/java/org/springframework/data/r2dbc/repository/AbstractR2dbcRepositoryIntegrationTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ public LegoSet(Integer id, String name, Integer manual) {
366366
@AllArgsConstructor
367367
@NoArgsConstructor
368368
@Getter
369+
@Setter
369370
static class Lego {
370371
@Id Integer id;
371372
}

src/test/java/org/springframework/data/r2dbc/repository/PostgresR2dbcRepositoryIntegrationTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@
3737
import org.springframework.context.annotation.FilterType;
3838
import org.springframework.data.annotation.Id;
3939
import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
40+
import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback;
4041
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
4142
import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory;
4243
import org.springframework.data.r2dbc.testing.ExternalDatabase;
4344
import org.springframework.data.r2dbc.testing.PostgresTestSupport;
4445
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
4546
import org.springframework.jdbc.core.JdbcTemplate;
47+
import org.springframework.r2dbc.core.DatabaseClient;
4648
import org.springframework.test.context.ContextConfiguration;
4749
import org.springframework.test.context.junit4.SpringRunner;
4850

@@ -70,6 +72,23 @@ static class IntegrationTestConfiguration extends AbstractR2dbcConfiguration {
7072
public ConnectionFactory connectionFactory() {
7173
return PostgresTestSupport.createConnectionFactory(database);
7274
}
75+
76+
@Bean
77+
public BeforeConvertCallback<LegoSet> autogeneratedId(DatabaseClient client) {
78+
79+
return (entity, table) -> {
80+
81+
if (entity.getId() == null) {
82+
return client.sql("SELECT nextval('person_seq');") //
83+
.map(row -> row.get(0, Integer.class)) //
84+
.first() //
85+
.doOnNext(entity::setId) //
86+
.thenReturn(entity);
87+
}
88+
89+
return Mono.just(entity);
90+
};
91+
}
7392
}
7493

7594
@Override
@@ -84,7 +103,7 @@ protected ConnectionFactory createConnectionFactory() {
84103

85104
@Override
86105
protected String getCreateTableStatement() {
87-
return PostgresTestSupport.CREATE_TABLE_LEGOSET_WITH_ID_GENERATION;
106+
return PostgresTestSupport.CREATE_TABLE_LEGOSET + ";CREATE SEQUENCE IF NOT EXISTS person_seq;";
88107
}
89108

90109
@Override

0 commit comments

Comments
 (0)