We now provide a reactive variant for auditing with ReactiveAuditingHandler and ReactiveIsNewAwareAuditingHandler.
Extracted common auditing functionality into AuditingHandlerSupport which serves as base class for AuditingHandler and ReactiveAuditingHandler.
Original Pull Request: #458
Update classes so that each member is declared on its own line. This
help to make them slightly easier to see when not using an IDE.
Original pull request: #448.
Replace the few occurrences where SLF4J was being used directly so that
all logging now happens via commons-logging. The log patterns used in
SLF4J messages have been replaced with `LogMessage` which was introduced
in Spring Framework 5.2.
Original pull request: #448.
Rename static final `CACHE` members to use the lowercase form. Although
the caches are static final, they are not constant values.
Original pull request: #448.
Encapsulate field and introduce getter for ConversionService. Add missing Override annotation. Add author tags. Minor cleanups.
Original pull request: #432.
We now expose a dedicated PersistentPropertyPathAccessor and optionally take options for both the read and write access to properties. On read, clients can define to eagerly receive null in case one of the path segments is null. By default, we reject those as it indicates that there might be an issue with the backing object if the client assumes it can look up the more deeply nested path to receive a result.
On write access clients can define to either reject, skip or log intermediate null segments where skip means, that the setting is just silently aborted. Clients can also control how to deal with collection and map intermediates. By default we now propagate the attempt to set a value to all collection or map items respectively. This could be potentially extended to provide a filter receiving both the property and property value to selectively propagate those calls in the future.
The separation of these APIs (PersistentPropertyAccessor and PersistentPropertyPathAccessor) is introduced as the latter can be implemented on top of the former and the former potentially being dynamically generated. The logic of the latter can then be clearly separated from the actual individual property lookup. ConvertingPropertyAccessor is now a PersistentPropertyPathAccessor, too, and overrides SimplePersistentPropertyPathAccessor.getTypedProperty(…) to plug in conversion logic. This allows custom collection types being used if the ConversionService backing the accessor can convert from and to Collection or Map respectively.
Deprecated all PersistentPropertyPath-related methods on PersistentPropertyAccessor for removal in 2.3.
MappingAuditableBeanWrapperFactory now uses these new settings to skip both null values as well as collection and map values when setting auditing metadata.
Related tickets: DATACMNS-1438, DATACMNS-1461, DATACMNS-1609.
We now skip PersistentPropertyPath instances pointing to auditing properties for which the path contains a collection or map path segment as the PersistentPropertyAccessor currently cannot handle those. A more extensive fix for that will be put in place for Moore but requires more extensive API changes which we don't want to ship in a Lovelace maintenance release.
Related tickets: DATACMNS-1461.
We now catch the MappingException produced by trying to set auditing property paths containing null intermediate segments and ignore those. A less expensive (non-Exception-based) approach is going to be introduced for Moore as it requires API changes to the property path setting APIs.
Related tickets: DATACMNS-1438.
PersistentPropertyAccessor is now generic to be able to retain the type information about the object it was created for and the return type of ….getBean(). Adapted client APIs.
We've changed the APIs in the auditing subsystem so that we support immutable entities, mostly through MappingAuditableBeanWrapperFactory that uses a PersistentPropertyAccessor.
PersistentEntity now exposes an ….isNew(…) method that exposes the same detection algorithm previously exposed through MappingContextIsNewStrategyFactory (Persistable in favor of the version property in favor of an identifier lookup). MappingContextIsNewStrategyFactory has been refactored to return an ad-hoc strategy to delegate to the newly introduced method.
The core message to implementing modules is that they should now prefer PersistentEntityInformation within their RepositoryFactorySupport implementation and move all customizations made in the store-specific EntityInformation implementation in PersistentEntity.
Based on the new infrastructure created by DATACMNS-1275, MappingAuditingMetadata now keeps PersistentPropertyPaths to point to the properties reflecting individual auditing metadata items rather than just PersistentPropertyPaths. With that in place we can now find those items in embedded types of the subject entity based on the detection setup of the MappingContext managing metadata for the entity.
As that means that multiple paths to a metadata item property can be found, we now use the first path found (the shortest one) for the lookup of the modification date.
Related tickets: DATACMNS-1275.
Removed unnecessary imports. Tiny refactoring to pull exception creation into static helper method. Made methods static in test cases where possible.
Original pull request: #273.
Using Instant as internal data type since it's a point in time without time zone which LocalDateTime isn't. Added necessary converters. Fixed one JodaTime converter that used UTC to use SystemDefault like other similar converters.
In case of a conversion failure the error message now contains the source type.
Original pull request: #273.
Marked all packages with Spring Frameworks @NonNullApi. Added Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fixed Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances.
Removed null handling from converters for JodaTime and ThreeTenBP. Introduced factory methods Page.empty() and Page.empty(Pageable). Introduced default methods getRequiredGetter(), …Setter() and …Field() on PersistentProperty to allow non-nullable lookups of members. The same for TypeInformation.getrequiredActualType(), …SuperTypeInformation().
Tweaked PersistentPropertyCreator.addPropertiesForRemainingDescriptors() to filter unsuitable PropertyDescriptors before actually trying to create a Property instance from them as the new stronger nullability requirements would cause exceptions downstream.
Lazy.get() now expects a non-null return value. Clients being able to cope with null need to call ….orElse(…).
Original pull request: #232.
Re-enabled test cases for handling of different date/time APIs in auditing. Tweaked the lookup of the last modified value to try to convert to LocalDateTime as well in case it's a subtype of the type requested. In combination with two newly introduced converters for local date type times in JodaTime and ThreeTenBP, this allows us to still convert legacy JodaTime and ThreeTenBP types to be used as well.
Make use of lambdas and method references though out the codebase. Remove no longer required generic type parameters.
Additionally remove unused imports and replace single element list initialization with dedicated singletonList.
Use Assertion overloads taking Supplier for dynamic assertion error messages.
Entities without an identifier previously an exception because the IsNewStrategyFactory wasn't able to determine a strategy even if there was no auditing to be applied in the first place.
We now eagerly check for auditability and skip the lookup for an IsNewStrategy completely in case that check returns false.
Related pull request: #189.
Extend AuditableBeanWrapper to allow access to the last modification date of a target object. Made AuditableBeanWrapperFactory an interface and renamed what’s been previously known under this name as DefaultAuditableBeanWrapperFactory.
The components previously relying on a MappingContext to lookup a PersistentEntity now use PersistentEntities to be able to back a collection of MappingContexts behind that and also avoid unmanaged types to be added to the MappingContext.
We now also register the JSR-310 and ThreeTen back-port converters with the ConversionService to be able to get and set auditing dates as these types.
To be able to customize the lookup of bean properties by persistent store we now expose a getPropertyAccessor(Object entity) method on PersistentEntity. It returns a PersistentPropertyAccessor which is basically an interface with a simplified API of BeanWrapper.
Reduced the plain BeanWrapper to not perform any type conversion to be able to drop the ConversionService dependency. To compensate for that we introduced a ConvertingPropertyAccessor that takes a ConversionService and delegates to a standard PersistentPropertyAccessor and applies conversions if necessary.
Refactored client APIs to use the PersistentPropertyAccessor instead of referring to BeanWrapper directly. Deprecated BeanWrapper.create(…) for removal in RC1.