Query methods returning dynamic projections based on a Class argument now properly apply projection conversion. Previously, classes not seen by the mapping context were skipped and that caused projecting query methods to return the actual entity type.
Closes#607
Rename method to renderForGeneratedValues to reflect its intended usage and enhance documentation.
Tweak Javadoc.
Closes: #483
Original pull request: #602.
Different R2DBC drivers expect generated keys when they are in camel case to be quoted or unquoted.
This can now be controlled by implementing `Dialect.renderForGeneratedKeys`.
Closes: #483
Original pull request: #602.
ByteToBooleanConverter is now marked as reading converter and we've added a writing converter with BooleanToByteConverter to ensure proper conversion. Previously, all byte values were converted to boolean resulting in data precision loss.
Closes#589
We now correctly obtain the target type for a persistent property that should be converted into an array value prior to constructing Parameter.
Previously, we fell back to the actual type without considering potential converters which left collection-like enum properties without a value with the enum array type that was potentially not supported by the database driver.
Closes#593
We now check in R2dbcEntityTemplate whether we need to skip the Id value if its value is null or a primitive using its default. Previously, the check was located in the converter. Converting an entity afteri ncrementing the version of a versioned entity would write the Id value as the entity was no longer considered to be new.
Closes#557.
Make count assertions case-insensitive regarding the count column name. Add missing license headers. Support DatabaseContainer without a database name.
See #230
We support Oracle's experimental R2DBC driver by providing a dialect including bind markers. Since the driver is not yet available from Maven Central and it requires module-path support for ServiceLoader discovery, we need to apply a few workarounds including absence check for our integration tests.
See #230
We now read the domain type instead of trying to materialize an interface if the type returned from the query method is implemented by the domain object handled by the repository.
Closes#519
We now apply the UPPER function regardless of whether we could resolve the criteria property to a column. Previously, we required a resolved property of a String type which prevented non-mapped properties from case-insensitive queries.
Closes#518
We now differentiate the result mapping based on projection type and query type. Previously, all projections used the domain type to map results first and then serve as backend for the projection proxy/DTO creation.
We now use direct result to DTO mapping for String-based queries to allow for a greater flexibility when declaring DTO result types. Interface-based projections and derived queries remain using the two-step process of result to domain type mapping and then mapping the domain type into the projection.
We now invoke the converter for query arguments of String-based queries (using the Query annotation or named queries) to convert the value into a type that can be used by the driver.
Previously all values were passed-thru which caused for e.g. enums to pass-thru these to the driver and the driver encode failed.
Results projected onto simple and primitive types that are null are no longer emitted.
A SQL query SELECT MAX(age) FROM my_table that returns a SQL NULL and that would be consumed as Long.class (Publisher<Long>) is an example for a primitive type that can be null. Since Reactive Streams prohibits the propagation of null values by a Publisher to a Subscriber the only viable option is to suppress null results by wrapping the mapping function into Optional result values and filter these values later to avoid null being emitted.
We now map results of exists queries to a boolean flag to ensure proper decoding. Previously, results were attempted to be mapped onto a primitive type which failed as there's no converter registered for Row to Boolean.
R2DBC Postgres Geo-types are now considered simple types that are passed-thru to the driver without further mapping. Types such as io.r2dbc.postgresql.codec.Circle or io.r2dbc.postgresql.codec.Box can be used directly in domain models and as bind parameters.
We now propagate auto-generated Id values to primitive Id properties if the value in the domain model is zero. This happens in addition to non-primitive values being null to ensure that generated values end up in the domain model.
We now initialize/increment the version of versioned entities (optimistic locking) after running the BeforeConvert callback. BeforeConvert callbacks may contain features such as auditing and if the auditing callback issues a isNew check, then the version would be already populated which leads to the auditing callback considering the entity not new anymore leaving the created date empty.
We now support the use of @Value in persistence constructors to compute values for constructor creation.
class MyDomainObject {
public MyDomainObject(long id, @Value("#root.my_column") String my_column, @Value("5+2") int computed) {
// …
}
}
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.
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.
We now provide EnumWriteSupport as base class for enum write converters that should be written as-is to the driver.
R2dbcCustomConversions can now also be created from a dialect for easier R2dbcCustomConversions creation.
We now exclude Id properties from being used in the INSERT field list if the Id value is zero and of a primitive type or if the value is null using a numeric wrapper type.
Added check for kotlin.Unit to AbstractR2dbcQuery#getExecutionToWrap. This case is essentially equivalent to a return type of Void, but the singleton Unit instance needs to be returned instead of discarding the result entirely.
It was also necessary to add a check to R2dbcQueryMethod#getEntityInformation, as otherwise a PersistentEntity is created for Unit, which leads to a new instance being created via reflection down the pipeline (which is probably not a thing that should happen).
Original pull request: #422.