Using Criteria.from(…) with multiple Criteria objects now uses properly AND combination along with group nesting to render a correct criteria. Previously, the INITIAL combinator in groups caused a mapping exception.
We now fall back to the column name when resolving a property path expression that maps into a simple-typed property. PropertyPath.from(…) fails internally as it attempts to look up a simple type from the MappingContext and this fails for primitive and simple types.
We now prevent converter registrations that enforce a conversion from JSR-310 types to java.util.Date. R2DBC drivers use natively JSR-310 types and some of them don't implement java.util.Date at all.
We now use the proper object instance when constructing statements for insert/update of versioned entities. Previously, we created a new instance that is associated with the incremented version number but we did not reuse that instance so the version increment remained invisible.
Added an integration test and tweaked the conversions to make it succeed.
The converter now does not rely on the driver to do the conversion anymore.
Original pull request: #360.
Formatting.
Added issue to test comments.
Removed the test for presence of the id in case of a potential optimistic locking exception.
A deleted row is also a case of a concurrent modification and therefore should trigger the OptimisticLockingException.
Original pull request: #314.
Consider projection properties as SELECT projection. Refactor distinct() into marker method without accepting a boolean flag. Make distinct field final. Update tests.
Original pull request: #346.
We now support distinct derived queries that are useful with projections to retrieve distinct results.
interface UserRepository extends Repository<User, Long> {
Mono<UserProjection> findDistinctByFirstName(String firstName);
}
interface UserProjection {
String getFirstName();
}
Original pull request: #346.
Consider modifying indicators in query execution. Consider absence of Criteria for delete and update queries. Add test.
Reformat code, update documentation.
Original pull request: #345.
Create database containers using the constructor accepting the image name to make sure that the exposed port gets registered. A recent change in Testcontainers caused that the port is no longer registered when using the default constructor.
Move query derivation infrastructure to Spring Data Relational. Adapt to newly introduced ValueFunction for deferred value mapping. Use query derivation in integration tests.
Tweak javadoc, add since and author tags, reformat code.
Related ticket: https://jira.spring.io/browse/DATAJDBC-514
Original pull request: #295.
We now accept StatementFilterFunction and ExecuteFunction via DatabaseClient to filter Statement execution. StatementFilterFunctions can be used to pre-process the statement or post-process Result objects.
databaseClient.execute(…)
.filter((s, next) -> next.execute(s.returnGeneratedValues("my_id")))
.filter((s, next) -> next.execute(s.fetchSize(25)))
databaseClient.execute(…)
.filter(s -> s.returnGeneratedValues("my_id"))
.filter(s -> s.fetchSize(25))
Original pull request: #308.
Refactored DefaultDatabaseClientUnitTests in order to make the relevant differences in setup easier to spot.
Formatting and nullability annotations.
Original pull request: #307.
We now support composition of Criteria objects to create a Criteria from one or more top-level criteria and to compose nested AND/OR Criteria objects:
Criteria.where("name").is("Foo")).and(Criteria.where("name").is("Bar").or("age")
.lessThan(49).or(Criteria.where("name").not("Bar").and("age").greaterThan(49))
Original pull request: #307.
We now support SpEL expressions in string-based queries to bind parameters for more dynamic queries. SpEL expressions are enclosed in :#{…} and rendered as synthetic named parameter so their values are substituted with bound parameters to avoid SQL injection attach vectors.
interface PersonRepository extends Repository<Person, String> {
@Query("SELECT * FROM person WHERE lastname = :#{'hello'}")
Mono<Person> findHello();
@Query("SELECT * FROM person WHERE lastname = :#{[0]} and firstname = :firstname")
Mono<Person> findByLastnameAndFirstname(@Param("value") String value, @Param("firstname") String firstname);
@Query("SELECT * FROM person WHERE lastname = :#{#person.name}")
Mono<Person> findByExample(@Param("person") Person person);
}
We now correctly reuse bind markers for named parameter substitution when using collection arguments to create dynamic argument lists. Previously, we allocated a new bind marker for each item in the collection which left the parameters intended for reuse unbound.
Use limit/offset instead of Page and accept Expression objects to declare a select list. Use SqlIdentifier in Update, Query, Criteria and fluent API.
Original pull request: #287.