Return List<DbChange<?>> in RelationalEntityWriters so AggregateChange can be assembled in less places to reduce the number of abstractions per method. Change ResultOrException in FunctionCollector to static class so instances no longer retain a reference to their enclosing class. Fix DbAction generics in AggregateChange. Replace simple constructors with Lombok usage. Javadoc, typos, formatting.
Original pull request: #79.
JdbcEntityWriter and JdbcDeleteEntityWriter now use an iterative approach based on PersistentPropertyPath instead of a recursive one.
DbAction is now split into multiple interfaces representing different variants of actions.
The implementations are simple value types without any implementation inheritance hierarchy.
All elements of a DbAction implementation are not null making usage and construction of instances much easier.
Original pull request: #79.
We now support configurable conversion by introducing CustomConversions and RelationalConverter. CustomConversions is a registry for converters that should be applied on a per-type basis for properties. CustomConversions is typically registered as bean and fed into RelationalMappingContext and the newly introduced RelationalConverter to consider simple types and conversion rules.
RelationalConverter with its implementation BasicRelationalConverter encapsulates conversion infrastructure such as EntityInstantiator, CustomConversions, and MappingContext that is required during relational value conversion. BasicRelationalConverter is responsible for simple value conversion and entity instantiation to pull related code together. It's not in full charge of row result to object mapping as this responsibility remains as part of DataAccessStrategy.
This change supersedes and removes ConversionCustomizer.
We now treat all properties of an entity mutable and continue to use the reflective PersistentPropertyAccessor implementation to make sure we don't break the old behavior of reflectively mutating immutable objects.
This is a workaround for now and has to be replaced by more exhaustive changes later.
Related tickets: DATACMNS-1322.
All packages now use @NoNullApi.
All warnings related to that fixed, except a few cases where upstream annotations are simply wrong.
Added null checks.
Fixed generic types where possible.
Improved Javadoc.
Code Formatting.
Replaced the direct use of EntityInstantiator with EntityInstantiators.
Moved it into the MappingContext because instantiation is part of the mapping process.
Original pull request: #68.
Moved to both the usage of the newly introduced PersistentEntity.isNew(…) and identifier lookups via PersistentEntity instead of using a custom EntityInformation implementation. JdbcRepositoryFactory now creates a PersistentEntityInformation, SimpleJdbcRepository simply works with a PersistentEntity.
Removed references to EntityInformation (a repository subsystem concept) from the template implementation. Removed BasicJdbcPersistentEntity and its tests entirely. JdbcAuditingEventListener is now using an IsNewAwareAuditingHandler.
Related tickets: DATACMNS-1333.
Moved the implementation from the DelimiterNamingStrategy into the NamingStrategy.
Dropped the support for different separators, since there is no good way to support it in the default implementations of an interface.
A getSeparator() method would bleed into the public API.
Also the added value of that flexibility seems limited.
During migration of the various test it became obvious that SqlGeneratorUnitTests was broken since test failures happend on a worker thread not on the main test thread.
This is fixed as well with this commit.
Such a parameter would only make sense with inheritance and we don't support inheritance at all in the moment.
Anything we need in order to support inheritance should be added once we do support inheritance.
Moved the dependency to NamedParameterJdbcOperations out of JdbcMappingContext. This revealed that despite the DataAccessStrategy abstraction, there are a couple of places in the query execution subsystem that work with a plain NamedParameterJdbcOperations instance, so that we now have to carry that around all the way from the repository factory bean. Improving that is subject for further changes.
A bit of JavaDoc and generics polish here and there.
Moved annotation processing of @Table and @Column into metamodel classes so that the NamingStrategy is only responsible for generic fallbacks. Allow @Column to be used as meta-annotation.
Simplified code by using constructor injection plus Lombok.
Removed superfluous handling of BeforeSave events with null entity.
Original pull request: #71.
Set logging level to WARN.
Removed a System.out call.
The detail loggers are still in the logback.xml as comments to be used for debugging and demonstration purposes.
Extracted ApplicationContext and Repository construction into method in order to make the actual test stand out more.
Split a test in two.
JavaDoc.
Code formatting.
Removed access modifiers in tests.
When enabled by using @EnableJdbcAuditing entities will get properties annotated with
* @CreatedBy
* @CreatedDate
* @LastModifiedBy
* @LastModifiedDate
updated when saved.
Original pull request: #64.
Rename AfterCreation event to AfterLoadEvent to align with other Spring Data modules. Add missing generics. Remove since tags pointing to version 2.0. Slightly tweak tests.
Original pull request: #58.
Event publishing moved into the JdbcEntityTemplate in order to ensure events for AggregateRoots.
Removed superfluous AggregateChange from AfterCreation event.
Original pull request: #58.
Renamed MyBatisNamingStrategy into NamespaceStrategy.
This avoids the confusion with the existing NamingStrategy.
Introduced a default instance.
Added a method creating a proper DataAccessStrategy with a NamespaceStrategy.
JavaDoc.
Original pull request: #44.
Made the DefaultDataAccessStrategy actually the default for JdbcRepositoryFactoryBean.
Therefore the injection of a strategy is optional.
Simplified constructors of DefaultDataAccessStrategy.
Created factory method to construct a correct DataAccessStrategy for use with MyBatis.
Did some untangling in the test application context configurations.
Original pull request: #54.
Removed DefaultNamingStrategy since we don't have GA release breaking APIs is still ok.
Introduced an instance of NamingStrategy so we don't have to create a new class whereever we just want the default implementation.
JavaDoc.
Formatting
Original pull request: #36.
This makes it nicer to overwrite certain aspects with a lambda instead of an anonymous class. Brings the naming strategy in line with pairs like WebMvcConfigurer / WebMvcConfigurerAdapter.
Original pull request: #36.
It is now ok for an entity to be “new” after saving.
We now only check that an entity is not new when the id is provided by the database.
If in such a case the entity is still “new” after saving it basically means obtaining the id from JDBC and setting it in the entity failed.
Removed need for entities in maps to have an id.
Together these changes simplify the requirements for Map values, which now can be value objects.
Instead of using Map.Entry we now use a dedicated class to hold key and value of a map entry.
This avoids side effects from the implementation of Map.Entry.
Replaced call to saveReferencedEntities with insertReferencedEntities which is simpler but equivalent since referenced entities always get only inserted, never updated.
Removed superfluous methods resulting from that change.
RowMapper can be configured either via the @Query(rowMapperClass = ….) or by registerign a RowMapperMap bean and register RowMapper per method return type.
@Bean
RowMapperMap rowMappers() {
return new ConfigurableRowMapperMap() //
.register(Person.class, new PersonRowMapper()) //
.register(Address.class, new AddressRowMapper());
}
When determining the RowMapper to use for a method the following steps are followed based on the return type of the method:
1. If the type is a simple type no RowMapper is used. Instead the query is expected to return a single row with a single column and a conversion to the return type is applied to that value.
2. The entity classes in the RowMapperMap are iterated until one is found that is a superclass or interface of the return type in question. The RowMapper registered for that class is used. Iterating happens in the order of registration, so make sure to register more general types after specific ones.
If applicable wrapper type like collections or Optional are unwrapped. So a return type of Optional<Person> will use the type Person in the steps above.