#447 - Deprecate ReactiveDataAccessStrategy.
ReactiveDataAccessStrategy is now deprecated in favor of using StatementMapper, UpdateMapper, and R2dbcConverter directly. The access strategy interface was introduced to allow pluggable access strategies in DatabaseClient. With moving DatabaseClient into Spring Framework, this approach is no longer required.
This commit is contained in:
@@ -174,7 +174,7 @@ Other strategies can also be put in place (if there is demand).
|
||||
[[mapping.custom.object.construction]]
|
||||
=== Customized Object Construction
|
||||
|
||||
The mapping subsystem allows the customization of the object construction by annotating a constructor with the `@PersistenceConstructor` annotation. The values to be used for the constructor parameters are resolved in the following way:
|
||||
The mapping subsystem allows the customization of the object construction by annotating a constructor with the `@PersistenceConstructor` annotation.The values to be used for the constructor parameters are resolved in the following way:
|
||||
|
||||
* If a parameter is annotated with the `@Value` annotation, the given expression is evaluated, and the result is used as the parameter value.
|
||||
* If the Java type has a property whose name matches the given field of the input row, then its property information is used to select the appropriate constructor parameter to which to pass the input field value.
|
||||
@@ -212,7 +212,8 @@ To selectively handle the conversion yourself, register one or more one or more
|
||||
You can use the `r2dbcCustomConversions` method in `AbstractR2dbcConfiguration` to configure converters.
|
||||
The examples <<mapping.configuration, at the beginning of this chapter>> show how to perform the configuration with Java.
|
||||
|
||||
NOTE: Custom top-level entity conversion requires asymmetric types for conversion.Inbound data is extracted from R2DBC's `Row`.
|
||||
NOTE: Custom top-level entity conversion requires asymmetric types for conversion.
|
||||
Inbound data is extracted from R2DBC's `Row`.
|
||||
Outbound data (to be used with `INSERT`/`UPDATE` statements) is represented as `OutboundRow` and later assembled to a statement.
|
||||
|
||||
The following example of a Spring Converter implementation converts from a `Row` to a `Person` POJO:
|
||||
|
||||
@@ -391,7 +391,7 @@ When working with multiple, potentially different databases, your application wi
|
||||
The provided `AbstractR2dbcConfiguration` support class assumes a single `ConnectionFactory` from which the `Dialect` gets derived.
|
||||
That being said, you need to define a few beans yourself to configure Spring Data R2DBC to work with multiple databases.
|
||||
|
||||
R2DBC repositories require either a `DatabaseClient` and `ReactiveDataAccessStrategy` or `R2dbcEntityOperations` to implement repositories.
|
||||
R2DBC repositories require `R2dbcEntityOperations` to implement repositories.
|
||||
A simple configuration to scan for repositories without using `AbstractR2dbcConfiguration` looks like:
|
||||
|
||||
[source,java]
|
||||
@@ -409,13 +409,9 @@ static class MySQLConfiguration {
|
||||
@Bean
|
||||
public R2dbcEntityOperations mysqlR2dbcEntityOperations(@Qualifier("mysql") ConnectionFactory connectionFactory) {
|
||||
|
||||
DefaultReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(MySqlDialect.INSTANCE);
|
||||
DatabaseClient databaseClient = DatabaseClient.builder()
|
||||
.connectionFactory(connectionFactory)
|
||||
.dataAccessStrategy(strategy)
|
||||
.build();
|
||||
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
|
||||
|
||||
return new R2dbcEntityTemplate(databaseClient, strategy);
|
||||
return new R2dbcEntityTemplate(databaseClient, MySqlDialect.INSTANCE);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
@@ -20,6 +20,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
import org.springframework.data.relational.core.query.Query;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
@@ -49,9 +50,20 @@ public interface R2dbcEntityOperations extends FluentR2dbcOperations {
|
||||
* @return the underlying {@link ReactiveDataAccessStrategy}.
|
||||
* @see ReactiveDataAccessStrategy
|
||||
* @since 1.1.3
|
||||
* @deprecated use {@link #getConverter()} instead as {@link ReactiveDataAccessStrategy} will be removed in a future
|
||||
* release.
|
||||
*/
|
||||
@Deprecated
|
||||
ReactiveDataAccessStrategy getDataAccessStrategy();
|
||||
|
||||
/**
|
||||
* Return the underlying {@link R2dbcConverter}.
|
||||
*
|
||||
* @return the underlying {@link R2dbcConverter}.
|
||||
* @since 1.2
|
||||
*/
|
||||
R2dbcConverter getConverter();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Methods dealing with org.springframework.data.r2dbc.query.Query
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionInformation;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
|
||||
import org.springframework.data.r2dbc.mapping.OutboundRow;
|
||||
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
|
||||
@@ -122,6 +123,20 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
this(databaseClient, getDataAccessStrategy(databaseClient));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient}, {@link R2dbcDialect} and
|
||||
* {@link R2dbcConverter}.
|
||||
*
|
||||
* @param databaseClient must not be {@literal null}.
|
||||
* @param dialect the dialect to use, must not be {@literal null}.
|
||||
* @param converter the dialect to use, must not be {@literal null}.
|
||||
* @since 1.2
|
||||
*/
|
||||
public R2dbcEntityTemplate(org.springframework.r2dbc.core.DatabaseClient databaseClient, R2dbcDialect dialect,
|
||||
R2dbcConverter converter) {
|
||||
this(databaseClient, new DefaultReactiveDataAccessStrategy(dialect, converter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link R2dbcEntityTemplate} given {@link DatabaseClient} and {@link ReactiveDataAccessStrategy}.
|
||||
*
|
||||
@@ -170,6 +185,15 @@ public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAw
|
||||
return this.dataAccessStrategy;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.core.R2dbcEntityOperations#getConverter()
|
||||
*/
|
||||
@Override
|
||||
public R2dbcConverter getConverter() {
|
||||
return this.dataAccessStrategy.getConverter();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
|
||||
|
||||
@@ -37,7 +37,10 @@ import org.springframework.r2dbc.core.PreparedOperation;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see org.springframework.r2dbc.core.PreparedOperation
|
||||
* @deprecated since 1.2 in favor of using direct usage of {@link StatementMapper},
|
||||
* {@link org.springframework.data.r2dbc.query.UpdateMapper} and {@link R2dbcConverter}.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ReactiveDataAccessStrategy {
|
||||
|
||||
/**
|
||||
|
||||
@@ -122,8 +122,10 @@ public @interface EnableR2dbcRepositories {
|
||||
*
|
||||
* @return
|
||||
* @see #entityOperationsRef()
|
||||
* @deprecated since 1.2, in favor of {@link #entityOperationsRef()}.
|
||||
*/
|
||||
String databaseClientRef() default "r2dbcDatabaseClient";
|
||||
@Deprecated
|
||||
String databaseClientRef() default "";
|
||||
|
||||
/**
|
||||
* Configures the name of the {@link org.springframework.data.r2dbc.core.R2dbcEntityOperations} bean to be used with
|
||||
@@ -134,7 +136,7 @@ public @interface EnableR2dbcRepositories {
|
||||
* @return
|
||||
* @since 1.1.3
|
||||
*/
|
||||
String entityOperationsRef() default "";
|
||||
String entityOperationsRef() default "r2dbcEntityTemplate";
|
||||
|
||||
/**
|
||||
* Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
|
||||
|
||||
@@ -98,12 +98,12 @@ public class R2dbcRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
|
||||
AnnotationAttributes attributes = config.getAttributes();
|
||||
|
||||
String entityOperationsRef = attributes.getString("entityOperationsRef");
|
||||
if (StringUtils.hasText(entityOperationsRef)) {
|
||||
builder.addPropertyReference("entityOperations", entityOperationsRef);
|
||||
} else {
|
||||
String databaseClientRef = attributes.getString("databaseClientRef");
|
||||
if (StringUtils.hasText(databaseClientRef)) {
|
||||
builder.addPropertyReference("databaseClient", attributes.getString("databaseClientRef"));
|
||||
builder.addPropertyReference("dataAccessStrategy", "reactiveDataAccessStrategy");
|
||||
} else {
|
||||
builder.addPropertyReference("entityOperations", attributes.getString("entityOperationsRef"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,10 @@ public class R2dbcRepositoriesRegistrarTests {
|
||||
static class EnableWithDatabaseClient {
|
||||
|
||||
@Bean
|
||||
public DatabaseClient r2dbcDatabaseClient() {
|
||||
return mock(DatabaseClient.class);
|
||||
public R2dbcEntityTemplate r2dbcEntityTemplate() {
|
||||
R2dbcEntityTemplate template = mock(R2dbcEntityTemplate.class);
|
||||
when(template.getDataAccessStrategy()).thenReturn(reactiveDataAccessStrategy());
|
||||
return template;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user