diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java index f1381b0e..f3bbb00b 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactory.java @@ -60,6 +60,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport { private final ReactiveDataAccessStrategy dataAccessStrategy; private final MappingContext, ? extends RelationalPersistentProperty> mappingContext; private final R2dbcConverter converter; + private final R2dbcEntityOperations operations; /** * Creates a new {@link R2dbcRepositoryFactory} given {@link DatabaseClient} and {@link MappingContext}. @@ -76,6 +77,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport { this.dataAccessStrategy = dataAccessStrategy; this.converter = dataAccessStrategy.getConverter(); this.mappingContext = this.converter.getMappingContext(); + this.operations = new R2dbcEntityTemplate(this.databaseClient, this.dataAccessStrategy); setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT); } @@ -93,6 +95,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport { this.dataAccessStrategy = operations.getDataAccessStrategy(); this.converter = dataAccessStrategy.getConverter(); this.mappingContext = this.converter.getMappingContext(); + this.operations = operations; setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT); } @@ -116,7 +119,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport { information); return getTargetRepositoryViaReflection(information, entityInformation, - new R2dbcEntityTemplate(this.databaseClient, this.dataAccessStrategy), this.converter); + operations, this.converter); } /* diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java index 3ec5db2b..bf1969e9 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/R2dbcRepositoryFactoryBean.java @@ -17,8 +17,12 @@ package org.springframework.data.r2dbc.repository.support; import java.io.Serializable; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.r2dbc.core.R2dbcEntityOperations; +import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; @@ -38,11 +42,12 @@ import org.springframework.util.Assert; * @see org.springframework.data.repository.reactive.ReactiveSortingRepository */ public class R2dbcRepositoryFactoryBean, S, ID extends Serializable> - extends RepositoryFactoryBeanSupport { + extends RepositoryFactoryBeanSupport implements ApplicationContextAware { private @Nullable DatabaseClient client; private @Nullable ReactiveDataAccessStrategy dataAccessStrategy; private @Nullable R2dbcEntityOperations operations; + private @Nullable ApplicationContext applicationContext; private boolean mappingContextConfigured = false; @@ -122,6 +127,15 @@ public class R2dbcRepositoryFactoryBean, S, ID exten return new R2dbcRepositoryFactory(operations); } + /* + * (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + /* * (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() @@ -134,6 +148,14 @@ public class R2dbcRepositoryFactoryBean, S, ID exten Assert.state(client != null, "DatabaseClient must not be null when R2dbcEntityOperations is not configured!"); Assert.state(dataAccessStrategy != null, "ReactiveDataAccessStrategy must not be null when R2dbcEntityOperations is not configured!"); + + R2dbcEntityTemplate template = new R2dbcEntityTemplate(client, dataAccessStrategy); + + if (applicationContext != null) { + template.setApplicationContext(applicationContext); + } + + operations = template; } else { dataAccessStrategy = operations.getDataAccessStrategy(); } diff --git a/src/test/java/org/springframework/data/r2dbc/repository/AbstractR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/AbstractR2dbcRepositoryIntegrationTests.java index 0a09b899..2955b7f7 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/AbstractR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/AbstractR2dbcRepositoryIntegrationTests.java @@ -366,6 +366,7 @@ public abstract class AbstractR2dbcRepositoryIntegrationTests extends R2dbcInteg @AllArgsConstructor @NoArgsConstructor @Getter + @Setter static class Lego { @Id Integer id; } diff --git a/src/test/java/org/springframework/data/r2dbc/repository/PostgresR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/PostgresR2dbcRepositoryIntegrationTests.java index cc4b500b..dec3031b 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/PostgresR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/PostgresR2dbcRepositoryIntegrationTests.java @@ -37,12 +37,14 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.data.annotation.Id; import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration; +import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback; import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory; import org.springframework.data.r2dbc.testing.ExternalDatabase; import org.springframework.data.r2dbc.testing.PostgresTestSupport; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -70,6 +72,23 @@ public class PostgresR2dbcRepositoryIntegrationTests extends AbstractR2dbcReposi public ConnectionFactory connectionFactory() { return PostgresTestSupport.createConnectionFactory(database); } + + @Bean + public BeforeConvertCallback autogeneratedId(DatabaseClient client) { + + return (entity, table) -> { + + if (entity.getId() == null) { + return client.sql("SELECT nextval('person_seq');") // + .map(row -> row.get(0, Integer.class)) // + .first() // + .doOnNext(entity::setId) // + .thenReturn(entity); + } + + return Mono.just(entity); + }; + } } @Override @@ -84,7 +103,7 @@ public class PostgresR2dbcRepositoryIntegrationTests extends AbstractR2dbcReposi @Override protected String getCreateTableStatement() { - return PostgresTestSupport.CREATE_TABLE_LEGOSET_WITH_ID_GENERATION; + return PostgresTestSupport.CREATE_TABLE_LEGOSET + ";CREATE SEQUENCE IF NOT EXISTS person_seq;"; } @Override