Skip shadowed properties that are not assignable to their shadowing type.
Extend tests. Document property overrides.
Original pull request: #390.
See #1911.
Prior to this commit, the lookup of types to be added as persistent entities for a given PersistentProperty used the actual property type which did not consider the association target type at all. Removed the usage of Optional for the entity type information and switched to use TypeInformation for the raw association target type so that it can be considered in ….getActualType().
We now throw MappingInstantiationException with a nested BeanInstantiationException in alignment to ReflectionEntityInstantiator when attempting to create a new instance of an abstract class.
Closes#2348.
We now detect the component type of jMolecules' Association as association target type in AbstractPersistentProperty. AnnotationBasedPersistentProperty keeps the lookup of the explicit @Reference around but falls back to the Association analysis for that.
@Reference is now only considered by AnnotationBasedPersistentProperty. It was previously also (erroneously) considered by AbstractPersistentProperty.
It was also changed to return `null` in case no association target type could be looked up instead of returning the sole property's type in case that is an entity. This was done to satisfy the behavior documented on the interface but also to avoid the call to isEntity() during the calculation which might use association information in turn and thus lead to a stack overflow. Reworded the contract of PersistentProperty.getAssociationTargetType() to emphasize the symmetry with ….isAssociation() in implementation classes.
Closes: #2344.
We now support composed annotation that are annotated with `@Value`. we also expose MergedAnnotations through PreferredConstructor.Parameter for further use by store modules that want to inspect constructor argument annotations.
Closes: #2332
Original Pull Request: #2333
We now resolve only the raw class when checking if a primary constructor argument is assignable to method parameters of the synthetic copy method.
Previously we used ResolvableType's assignability check which considered generic type arguments. As the type resolution between the KType and copy method type is not symmetric, the check only succeeded in cases where both types could be resolved to the same type/assignable type. Using projections or Any caused asymmetric resolution and therefor the assignability check returned non-assignable.
Closes#2336.
We now resolve the copy method for Kotlin data classes that match the primary constructor. Previously, copy method resolution could find a secondary copy method as we didn't check for the primary constructor structure (parameter names and types).
Closes#2324.
We no recognize properties of type org.jmolecules.ddd.types.Association as associations in our PersistentProperty model.
Also, we now register JMolecules Converter implementations for Association and Identifier in CustomConversions so that they can persisted like their embedded primitive value out of the box.
Fixes#2315.
Original pull request: #2316.
In oder to preserve contextual information the PersistentPropertyPathFactory now obtains EntityInformation for properties from the MappingContext via their PersistentProperty representation instead of plain the TypeInformation as the former contains more information about the actual type and signatures.
Closes#2293.
Original pull request: #2294.
We now cache the negative outcome of PreferredConstructor.isConstructorParameter(…) to avoid iterations and iterator allocations which roughly improves typical converter usage by roughly 32%.
Before:
Benchmark Mode Cnt Score Error Units
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndField thrpt 10 6848447,474 ± 554354,377 ops/s
After
Benchmark Mode Cnt Score Error Units
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndField thrpt 10 9071099,879 ± 1423166,087 ops/s
Closes#2295.
We now leniently skip parameter name resolution for types using unsigned types. The issue is caused by Kotlin's DefaultConstructorMarker that doesn't report a parameter name.
Closes#2215
Allow obtaining an EvaluationContext with a reduced set of extensions that are required for ExpressionDependencies instead of initializing all extensions.
We now use a dedicated GetOptions instance for the lookup of the parent path in case SetOptions is defined to skip nulls so that the lookup does not fail if the parent path contains a null value.
Use a more lenient approach, that allows metadata creation, when looking up persistent entities. This allows eg. a configured AuditingHandler to kick in without having to register an initial entity set in first place.
Original pull request: #462.
Use KotlinDetector instead of ReflectionUtils.isKotlinClass(…). Use replacement MethodParameter(…).withContainingClass(…) instead of GenericTypeResolver.resolveParameterType(…). Use MergedAnnotations.from(…).isPresent(…) instead of AnnotationUtils.isAnnotationMetaPresent(…).
kotlin.Unit is now considered a simple type to avoid PersistentEntity creation.
ReflectionUtils.isVoid(…) now encapsulates the check so that calling code doesn't need to check if Kotlin is on the class path.
We now reuse the new bean in InstantiationAwarePropertyAccessor when setting properties. Previously, we used the initial bean state as the bean was held by a delegate PersistentPropertyAccessor which caused only the last set property to be visible.
Always fall back to reflection when the system property for org.graalvm.nativeimage.imagecode is set.
This is required because on the fly code generation is not supported in this case.
Original pull request: #456.
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.
Replace the use of an anonymous class with a static initializer block.
This update also changes the constant to an unmodifiable variant.
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.
Use mutated object as guard for synchronization. Copy discovered callbacks to cached callbacks.
Reduce concurrency in unit test to reduce test load. Guard synchronization with timeouts.
Original pull request: #446.
Switch property parameter cache from HashMap and external locks to ConcurrentHashMap to improve multi-threaded locking behavior during isConstructorParameter(…) initialization.
Original pull request: #437.
Reorder constructor filtering with the goal to delay/avoid potentially expensive PersistenceConstructor creation with parameter lookup as much as possible.
The lookup is (in a default setup) only done once per domain type, but depending on the number of entities to inspect the change can help save some cycles for larger domains.
Before:
Benchmark Mode Cnt Score Error Units
EntityMetadataBenchmark.alwaysNew thrpt 10 224318,163 ± 42542,453 ops/s
After:
Benchmark Mode Cnt Score Error Units
EtityMetadataBenchmark.alwaysNew thrpt 10 420053,505 ± 9288,093 ops/s
public class DomainType {
private String id;
private @Id String theId;
private String firstname, lastname;
private Integer age;
public DomainType(String id, String theId, String firstname, String lastname, Integer age) {
this.id = id;
this.theId = theId;
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
@PersistenceConstructor
public DomainType(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
}
Original pull request: #440.
We now detect whether callbacks are present before we create result lists instead of always allocating a Collection. CallbackRetriever now also returns a cached variant of its list of callbacks instead of always allocating a new ArrayList.
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.