AbstractMappingContext.hasPersistentEntityFor(…) now also properly consideres the empty Optional as non-presence as that is held to allow to distinguish between a type completely unkown to the context, or already known but not considered a persistent entity.
Related pull request: #258.
In AbstractPersistentProperty, we now resolve the potentially generic return and parameter types of getters and setters. To achieve that Property has now been made aware of the actual owning type.
The new name currently delegates to old version, so classes only implementing the old method still work. Old name is deprecated.
Original pull request: #243.
Add Nullable annotation to ParsingUtils, Sort.Order and PropertyValueProvider.
Add getRequiredAnnotation(…) to PersistentEntity and PersistentProperty to provide methods returning required, non-null annotations.
We now discover Kotlin constructors and apply parameter defaulting to allow construction of immutable value objects. Constructor discovery uses primary constructors by default and considers PersistenceConstructor annotations.
KotlinClassGeneratingEntityInstantiator can instantiate Kotlin classes with default parameters by resolving the synthetic constructor. Null values translate to parameter defaults.
class Person(val firstname: String = "Walter") {
}
class Address(val street: String, val city: String) {
@PersistenceConstructor
constructor(street: String = "Unknown", city: String = "Unknown", country: String) : this(street, city)
}
Original pull request: #233.
We're now favoring the generic TypeInformation over trying to resolve the property type via field or PropertyDescriptor as only the former does proper generic type resolution.
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.
As the calculation of a PersistentPropertyPath instances is rather expensive and they're heavily used in downstream mapping operations (e.g. query and fields mapping in MongoDB) we now cache the instances created per base type and property path.
Move MappingException from o.s.d.mapping.model to o.s.d.mapping package and use it for getRequired* methods in MappingContext instead of throwing IllegalArgumentException. Further on we’ve consolidated usage of IllegalArgumentException and IllegalStateException. Along that IllegalMappingException was removed in favor or MappingException.
BasicPersistentEntity now looks up all properties by annotation instead of just returning the first one found. We’ve kept the original methods behavior and updated the comment as well as introduced getPersistentProperties returning all matching properties.
All overloaded methods are now available in SPeL expressions. Among methods with identical argument list from different sources in the same extension (extension, root object, aliases) the last one in the order in parens wins. If there is more than one method for an application the following rules are applied: if there is one method with exact matching types in the argument list it is used, otherwise an exception is thrown.
Original pull request: #217.
Extracted CustomConversions — whose code has largely been duplicated between the MongoDB, Couchbase and Cassandra modules — into Spring Data Commons. Store-specific extensions can now be contributed via a StoreConversions value type that carries both, store-specific default converters as well as a store-specific SimpleTypeHolder to augment the default list of simple types.
Removed SimpleTypeHolders public default constructor in favour of a protected one and a static DEFAULT instance for plain references.
Original pull request: #210.
The new method allows to look up identifiers and immediately fail in the case of absence. Introduced the method as default method but also a new base type TargetAwareIdentifierAccessor to throw an exception with more context, i.e. the actual target bean we try to look up the identifier on.
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.
Preserve underscores in variable names (eg. String foo_bar) when resolving the actual type information for the property via PropertyPath by quoting (Pattern#quote) the property name.
We now consider property annotations as merged annotations when initially scanning for annotations in a property declaration. Composed annotations such as declared outside our code are captured correctly because they use an own type that is not queried by users of PersistentProperty. Own, revised annotations, using @AliasFor providing an alias for annotation values require merged annotation processing.
Previously, annotations were cached as-is without resolving @AliasFor. This caused a later lookup via findAnnotation(…) to return the cached annotation without aliasing. Because the annotation was cached, no further lookup via AnnotatedElementUtils.findMergedAnnotation(…) was attempted.
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { FIELD, METHOD })
public @interface RevisedAnnnotationWithAliasFor {
@AliasFor("value")
String name() default "";
@AliasFor("name")
String value() default "";
}
public class Person {
@RevisedAnnnotationWithAliasFor(value = "spring")
String firstname;
}
PersistentProperty firstname = …
property.findAnnotation(…) returned previously @RevisedAnnnotationWithAliasFor(value = "spring", name = "")
now we return @RevisedAnnnotationWithAliasFor(value = "spring", name = "spring")
We now prefer an explicit Method.getParameterCount() over accessing the parameter types array and its length to avoid the overhead of cloning the array.
Original pull request: #187.
Previously a null value was added to the list of associations if it was handed to BasicaPersistentEntity.addAssociation(…). We now drop those null values and log a warning as it usually indicates a MappingContext implementation identifying a property as association but subsequently failing to look it up.
Previously, ClassGeneratingPropertyAccessorFactory uses boxed types for primitive type setters. This threw NoSuchMethodExceptions and caused ExceptionInInitializerError as the generated class could not be initialized. We now use the appropriate argument type to look up setters.
Also, we now only generate accessor usage if the property is configured to use property access in the first place.
Original pull request: #178.
We now explicitly report the given object's type and the one expected in case of a mismatch when BasicPersistentEntity.getPropertyAccessor(…) is invoked.
Simplified test case. Formatting in ClassGeneratingPropertyAccessorFactory.
Related tickets: DATACMNS-809.
Original pull request: #161.
Related pull request: #160.
Reproduce issue accessing persistent properties from interface-based entities using the ClassGeneratingPropertyAccessorFactory.
Related tickets: DATACMNS-809.
Original pull request: #161.
Related pull request: #160.
Removed DefaultPersistentPropertyAccessorFactory as it only delegates to the class generating one. Tweaked AbstractMappingContext to actually use the latter in the first place. Introduced BeanWrapperPropertyAccessorFactory to implement the default behavior of using a BeanWrapper and initialize BasicPersistentEntity to avoid a null clause in getPersistentPropertyAccessor(…).
Removed getPersistentPropertyAccessorFactory and rather rely on ReflectionTestUtils in tests to avoid additional API being exposed.
Original pull request: #159.
PersistentPropertyAccessorFactory can be set on a BasicPersistentEntity. This is done by AbstractMappingContext once the entity is verified. This change reduces the count of PersistentPropertyAccessorFactory instances and performs the isSupported check only once, when initializing the entity.
Original pull request: #159.
Made as many methods in ClassGeneratingPropertyAccessorFactory static as possible. Some code formatting. Some warning suppressions where needed.
Original pull request: #159.
We now support generated PersistentPropertyAccessors when using Java 7 and if property/association name hashCodes are unique within a PersistentEntity.
Generated PersistentPropertyAccessors provide optimized access to properties. They use either MethodHandles or direct property/field access, depending on the visibility/final modifiers of the entity type and its members. A generated PersistentPropertyAccessor is injected into the originating class loader of the entity class to enable optimizations for package-default/protected member access.
Original pull request: #159.