We now expose what type or PersistentEntity an association points to by trying to match the association's type to identifier types to entities. In case multiple matches are found, we require the user to explicitly declare the target type via @Reference.
Introduced PersistentEntities.of(…) for convenience.
We now consider all types in the java.time package as simple types to prevent deep reflective access. We are already excluding java.lang types for the same reason.
Original pull request: #286.
MappingContext now exposes a method to detect all property paths pointing to properties matching a given predicate.
Extracted PersistentPropertyPath creation into a dedicated factory class so that it can be tested individually. DefaultPersistentPropertyPath now exposes a ….containsPropertyOfType(…) to detect whether we've already processed a particular type in the path. Also applied a bit of Java 8 and Lombok polish.
InvalidPersistentPropertyPath now collects suggested alternatives to create a better exception message. PersistentEntities now allows to map over a MappingContext and PersistentEntity that a given type is corresponding to. Streamable now exposes an ….isEmpty(). Removed references to equivalent methods implemented in subtypes.
We now explicitly check for an enum type in SimpleTypeHolder.isSimpleType(…) and resort to true immediately. Before that an enum implementing an interface could have seen a false for the actual enum type in case the interface type had been checked first and (correctly) produced a false. In the check for the actual enum type, depending on the iteration order through the cached values we could've hit the cached false for the interface or the cached true value for Enum.
Previously, a call to AbstractMappingContext.getPersistentEntity(PersistentProperty) would've added potentially leniently added the type of the given PersistentProperty, no matter whether it's actually considered to be an entity in the first place. We now defensively check for whether the given property is to be considered an entity (taking potentially registered converters into account) before the potentially entity-creating by-type lookup.
More fixes of imports. Removed obsolete generics in constructor expressions. Removed a couple of compiler warnings in test cases. Removed assumption for test case to only run on JDK 9.
Original pull request: #259.
Make sure to use concurrent collection implementations for properties holding mutable state. Especially the ones making use of computeIfAbsent(…).
Usage of ConcurrentReferenceHashMap allows us to move on without additional changes as it allows to store null values, whereas ConcurrentHashMap would require us to store explicit NullValue placeholders for such cases, potentially causing trouble in downstream store specific projects.
JMH Benchmarks done with the Spring Data MongoDB mapping layer showed a potential performance loss of up to 5%. However a comparison between ConcurrentReferenceHashMap and ConcurrentHashMap did not show any significant difference in performance.
Original pull request: #259.
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.