@@ -9,7 +9,7 @@ The following sections explain how to migrate to a newer version of Spring Data
|
||||
|
||||
Spring Data R2DBC was developed with the intent to evaluate how well R2DBC can integrate with Spring applications.
|
||||
One of the main aspects was to move core support into Spring Framework once R2DBC support has proven useful.
|
||||
Spring Framework 5.3 ships with a new module: Spring R2DBC.
|
||||
Spring Framework 5.3 ships with a new module: Spring R2DBC (`spring-r2dbc`).
|
||||
|
||||
`spring-r2dbc` ships core R2DBC functionality (a slim variant of `DatabaseClient`, Transaction Manager, Connection Factory initialization, Exception translation) that was initially provided by Spring Data R2DBC. The 1.2.0 release aligns with what's provided in Spring R2DBC by making several changes outlined in the following sections.
|
||||
|
||||
@@ -37,13 +37,13 @@ Spring R2DBC provides a slim exception translation variant without an SPI for no
|
||||
=== Usage of replacements provided by Spring R2DBC
|
||||
|
||||
To ease migration, several deprecated types are now subtypes of their replacements provided by Spring R2DBC. Spring Data R2DBC has changes several methods or introduced new methods accepting Spring R2DBC types.
|
||||
Specifically the following classes are affected:
|
||||
Specifically the following classes are changed:
|
||||
|
||||
* `R2dbcEntityTemplate`
|
||||
* `R2dbcDialect`
|
||||
* Types in `org.springframework.data.r2dbc.query`
|
||||
|
||||
We recommend that you review your imports if you work with these types directly.
|
||||
We recommend that you review and update your imports if you work with these types directly.
|
||||
|
||||
=== Breaking Changes
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import io.r2dbc.spi.Connection;
|
||||
* @author Mark Paluch
|
||||
* @see SimpleConnectionHandle
|
||||
* @see ConnectionHolder
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead.
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC without replacement.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated
|
||||
|
||||
@@ -27,7 +27,7 @@ import io.r2dbc.spi.ConnectionFactory;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see ConnectionFactoryUtils#closeConnection
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection} instead.
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC without replacement.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface SmartConnectionFactory extends ConnectionFactory {
|
||||
|
||||
@@ -27,7 +27,8 @@ import org.springframework.util.Assert;
|
||||
* Utility methods for executing a {@link DatabasePopulator}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC. Use {@link org.springframework.r2dbc.connection.init} instead.
|
||||
* @deprecated since 1.2 in favor of Spring R2DBC. Use
|
||||
* {@link org.springframework.r2dbc.connection.init.DatabasePopulator#populate(ConnectionFactory)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class DatabasePopulatorUtils {
|
||||
|
||||
@@ -68,10 +68,11 @@ public interface ReactiveDataAccessStrategy {
|
||||
* @since 1.1
|
||||
* @deprecated since 1.2, use {@link #getBindValue(Parameter)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
SettableValue getBindValue(SettableValue value);
|
||||
|
||||
/**
|
||||
* Return a potentially converted {@link SettableValue} for strategies that support type conversion.
|
||||
* Return a potentially converted {@link Parameter} for strategies that support type conversion.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Optional;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.r2dbc.convert.R2dbcConverter;
|
||||
import org.springframework.data.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
|
||||
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
|
||||
@@ -185,8 +184,7 @@ public class R2dbcRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||
return new StringBasedR2dbcQuery(queryMethod, this.databaseClient, this.converter, EXPRESSION_PARSER,
|
||||
this.evaluationContextProvider);
|
||||
} else {
|
||||
return new PartTreeR2dbcQuery(queryMethod, this.databaseClient, this.converter,
|
||||
this.dataAccessStrategy);
|
||||
return new PartTreeR2dbcQuery(queryMethod, this.databaseClient, this.converter, this.dataAccessStrategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.r2dbc.repository.support;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
|
||||
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.data.r2dbc.mapping.SettableValue
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
suspend fun DatabaseClient.GenericExecuteSpec.await() {
|
||||
then().awaitFirstOrNull()
|
||||
}
|
||||
@@ -34,6 +35,7 @@ suspend fun DatabaseClient.GenericExecuteSpec.await() {
|
||||
* @author Ibanga Enoobong Ime
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<*>.bind(index: Int, value: T?) = bind(index, SettableValue.fromOrEmpty(value, T::class.java))
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,7 @@ inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<*>.bind(index: Int,
|
||||
* @author Ibanga Enoobong Ime
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.bind(index: Int, value: T?) = bind(index, SettableValue.fromOrEmpty(value, T::class.java))
|
||||
|
||||
/**
|
||||
@@ -52,6 +55,7 @@ inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.bind(index: Int,
|
||||
* @author Ibanga Enoobong Ime
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<*>.bind(name: String, value: T?) = bind(name, SettableValue.fromOrEmpty(value, T::class.java))
|
||||
|
||||
/**
|
||||
@@ -61,6 +65,7 @@ inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<*>.bind(name: Strin
|
||||
* @author Ibanga Enoobong Ime
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.bind(name: String, value: T?) = bind(name, SettableValue.fromOrEmpty(value, T::class.java))
|
||||
|
||||
/**
|
||||
@@ -69,6 +74,7 @@ inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.bind(name: String
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.asType(): DatabaseClient.TypedExecuteSpec<T> =
|
||||
`as`(T::class.java)
|
||||
|
||||
@@ -78,6 +84,7 @@ inline fun <reified T : Any> DatabaseClient.GenericExecuteSpec.asType(): Databas
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.GenericSelectSpec.asType(): DatabaseClient.TypedSelectSpec<T> =
|
||||
`as`(T::class.java)
|
||||
|
||||
@@ -86,6 +93,7 @@ inline fun <reified T : Any> DatabaseClient.GenericSelectSpec.asType(): Database
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
suspend fun <T> DatabaseClient.TypedExecuteSpec<T>.await() {
|
||||
then().awaitFirstOrNull()
|
||||
}
|
||||
@@ -96,6 +104,7 @@ suspend fun <T> DatabaseClient.TypedExecuteSpec<T>.await() {
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<T>.asType(): DatabaseClient.TypedExecuteSpec<T> =
|
||||
`as`(T::class.java)
|
||||
|
||||
@@ -104,6 +113,7 @@ inline fun <reified T : Any> DatabaseClient.TypedExecuteSpec<T>.asType(): Databa
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
suspend fun <T> DatabaseClient.InsertSpec<T>.await() {
|
||||
then().awaitFirstOrNull()
|
||||
}
|
||||
@@ -114,6 +124,7 @@ suspend fun <T> DatabaseClient.InsertSpec<T>.await() {
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.InsertIntoSpec.into(): DatabaseClient.TypedInsertSpec<T> =
|
||||
into(T::class.java)
|
||||
|
||||
@@ -123,6 +134,7 @@ inline fun <reified T : Any> DatabaseClient.InsertIntoSpec.into(): DatabaseClien
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.GenericInsertSpec<*>.value(name: String, value: T?) = value(name, SettableValue.fromOrEmpty(value, T::class.java))
|
||||
|
||||
|
||||
@@ -132,6 +144,7 @@ inline fun <reified T : Any> DatabaseClient.GenericInsertSpec<*>.value(name: Str
|
||||
*
|
||||
* @author Jonas Bark
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.SelectFromSpec.from(): DatabaseClient.TypedSelectSpec<T> =
|
||||
from(T::class.java)
|
||||
|
||||
@@ -141,6 +154,7 @@ inline fun <reified T : Any> DatabaseClient.SelectFromSpec.from(): DatabaseClien
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.UpdateTableSpec.table(): DatabaseClient.TypedUpdateSpec<T> =
|
||||
table(T::class.java)
|
||||
|
||||
@@ -150,5 +164,6 @@ inline fun <reified T : Any> DatabaseClient.UpdateTableSpec.table(): DatabaseCli
|
||||
*
|
||||
* @author Jonas Bark
|
||||
*/
|
||||
@Deprecated("Deprecated in favor of Spring R2DBC's DatabaseClient")
|
||||
inline fun <reified T : Any> DatabaseClient.DeleteFromSpec.from(): DatabaseClient.TypedDeleteSpec<T> =
|
||||
from(T::class.java)
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.data.r2dbc.mapping.SettableValue;
|
||||
import org.springframework.data.r2dbc.testing.StatementRecorder;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.query.Update;
|
||||
@@ -68,7 +69,7 @@ public class ReactiveUpdateOperationUnitTests {
|
||||
StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE"));
|
||||
|
||||
assertThat(statement.getSql()).isEqualTo("UPDATE person SET THE_NAME = $1");
|
||||
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg"));
|
||||
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Heisenberg"));
|
||||
}
|
||||
|
||||
@Test // gh-410
|
||||
@@ -87,7 +88,7 @@ public class ReactiveUpdateOperationUnitTests {
|
||||
StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("UPDATE"));
|
||||
|
||||
assertThat(statement.getSql()).isEqualTo("UPDATE table SET THE_NAME = $1");
|
||||
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, SettableValue.from("Heisenberg"));
|
||||
assertThat(statement.getBindings()).hasSize(1).containsEntry(0, Parameter.from("Heisenberg"));
|
||||
}
|
||||
|
||||
@Test // gh-220
|
||||
|
||||
@@ -32,10 +32,11 @@ import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
|
||||
import org.springframework.data.r2dbc.dialect.MySqlDialect;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.data.r2dbc.dialect.SqlServerDialect;
|
||||
import org.springframework.data.r2dbc.repository.config.mysql.MySqlPersonRepository;
|
||||
import org.springframework.data.r2dbc.repository.config.sqlserver.SqlServerPersonRepository;
|
||||
import org.springframework.r2dbc.core.DatabaseClient;
|
||||
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link R2dbcRepositoriesRegistrar}.
|
||||
@@ -86,8 +87,8 @@ public class R2dbcRepositoriesRegistrarTests {
|
||||
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.builder().bindMarkers(BindMarkersFactory.anonymous("?"))
|
||||
.connectionFactory(connectionFactory).build();
|
||||
|
||||
return new R2dbcEntityTemplate(databaseClient, strategy);
|
||||
}
|
||||
@@ -107,8 +108,8 @@ public class R2dbcRepositoriesRegistrarTests {
|
||||
public DatabaseClient sqlserverDatabaseClient(
|
||||
@Qualifier("sqlserverConnectionFactory") ConnectionFactory connectionFactory,
|
||||
@Qualifier("sqlserverDataAccessStrategy") ReactiveDataAccessStrategy mysqlDataAccessStrategy) {
|
||||
return DatabaseClient.builder().connectionFactory(connectionFactory).dataAccessStrategy(mysqlDataAccessStrategy)
|
||||
.build();
|
||||
return DatabaseClient.builder().connectionFactory(connectionFactory)
|
||||
.bindMarkers(BindMarkersFactory.anonymous("?")).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user