From ac9f99fc5453b8f41eacd5f3c36689aa8e4a2d83 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Fri, 28 Jan 2022 11:05:50 +0100 Subject: [PATCH] Polishing of annotation model for object creators. Move to @PersistenceCreator as canonical annotation to explicitly express constructors and methods to be used to create domain object instances from persistence operations. Removed @FactoryMethod as it's not needed anymore. @PersistenceConstructor is now deprecated. Renamed EntityCreatorMetadata(Support|Discoverer) to InstanceCreatorMetadata(Support|Discoverer) to avoid further manifestation of the notion of an entity in the metamodel as it's not used to only handle entities. Issue #2476. --- src/main/asciidoc/object-mapping.adoc | 14 ++++---- .../data/annotation/FactoryMethod.java | 33 ------------------- .../annotation/PersistenceConstructor.java | 8 +++-- ...nnotation.java => PersistenceCreator.java} | 8 ++--- .../data/mapping/FactoryMethod.java | 3 +- ...data.java => InstanceCreatorMetadata.java} | 7 ++-- ...va => InstanceCreatorMetadataSupport.java} | 9 ++--- .../data/mapping/PersistentEntity.java | 6 ++-- .../data/mapping/PreferredConstructor.java | 2 +- .../mapping/model/BasicPersistentEntity.java | 19 ++++------- .../ClassGeneratingEntityInstantiator.java | 29 ++++++++-------- ...=> InstanceCreatorMetadataDiscoverer.java} | 18 +++++----- .../InstantiationAwarePropertyAccessor.java | 2 +- ...tlinClassGeneratingEntityInstantiator.java | 18 +++++----- .../model/MappingInstantiationException.java | 12 +++---- ...ersistentEntityParameterValueProvider.java | 6 ++-- .../model/PreferredConstructorDiscoverer.java | 11 +++---- .../model/ReflectionEntityInstantiator.java | 5 +-- ...GeneratingEntityInstantiatorUnitTests.java | 25 +++++++------- ...ityCreatorMetadataDiscovererUnitTests.java | 15 ++++----- .../mapping/model/FactoryMethodUnitTests.java | 5 ++- ...EntityParameterValueProviderUnitTests.java | 5 ++- ...ReflectionEntityInstantiatorUnitTests.java | 5 ++- ...ssGeneratingEntityInstantiatorUnitTests.kt | 10 +++--- ...ionEntityInstantiatorDataClassUnitTests.kt | 4 +-- 25 files changed, 117 insertions(+), 162 deletions(-) delete mode 100644 src/main/java/org/springframework/data/annotation/FactoryMethod.java rename src/main/java/org/springframework/data/annotation/{EntityCreatorAnnotation.java => PersistenceCreator.java} (82%) rename src/main/java/org/springframework/data/mapping/{EntityCreatorMetadata.java => InstanceCreatorMetadata.java} (86%) rename src/main/java/org/springframework/data/mapping/{EntityCreatorMetadataSupport.java => InstanceCreatorMetadataSupport.java} (87%) rename src/main/java/org/springframework/data/mapping/model/{EntityCreatorMetadataDiscoverer.java => InstanceCreatorMetadataDiscoverer.java} (85%) diff --git a/src/main/asciidoc/object-mapping.adoc b/src/main/asciidoc/object-mapping.adoc index 5f8592996..6a99e0b00 100644 --- a/src/main/asciidoc/object-mapping.adoc +++ b/src/main/asciidoc/object-mapping.adoc @@ -17,9 +17,9 @@ This means we need two fundamental steps: Spring Data automatically tries to detect a persistent entity's constructor to be used to materialize objects of that type. The resolution algorithm works as follows: -1. If there is a single static factory method annotated with `@FactoryMethod` then it is used. +1. If there is a single static factory method annotated with `@PersistenceCreator` then it is used. 2. If there is a single constructor, it is used. -3. If there are multiple constructors and exactly one is annotated with `@PersistenceConstructor`, it is used. +3. If there are multiple constructors and exactly one is annotated with `@PersistenceCreator`, it is used. 4. If there's a no-argument constructor, it is used. Other constructors will be ignored. @@ -205,9 +205,9 @@ Even if the intent is that the calculation should be preferred, it's important t <4> The `comment` property is mutable is populated by setting its field directly. <5> The `remarks` properties are mutable and populated by setting the `comment` field directly or by invoking the setter method for <6> The class exposes a factory method and a constructor for object creation. -The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through `@PersistenceConstructor`. +The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through `@PersistenceCreator`. Instead, defaulting of properties is handled within the factory method. -If you want Spring Data to use the factory method for object instantiation, annotate it with `@FactoryMethod`. +If you want Spring Data to use the factory method for object instantiation, annotate it with `@PersistenceCreator`. [[mapping.general-recommendations]] == General recommendations @@ -217,7 +217,7 @@ Also, this avoids your domain objects to be littered with setter methods that al If you need those, prefer to make them package protected so that they can only be invoked by a limited amount of co-located types. Constructor-only materialization is up to 30% faster than properties population. * _Provide an all-args constructor_ -- Even if you cannot or don't want to model your entities as immutable values, there's still value in providing a constructor that takes all properties of the entity as arguments, including the mutable ones, as this allows the object mapping to skip the property population for optimal performance. -* _Use factory methods instead of overloaded constructors to avoid ``@PersistenceConstructor``_ -- With an all-argument constructor needed for optimal performance, we usually want to expose more application use case specific constructors that omit things like auto-generated identifiers etc. +* _Use factory methods instead of overloaded constructors to avoid ``@PersistenceCreator``_ -- With an all-argument constructor needed for optimal performance, we usually want to expose more application use case specific constructors that omit things like auto-generated identifiers etc. It's an established pattern to rather use static factory methods to expose these variants of the all-args constructor. * _Make sure you adhere to the constraints that allow the generated instantiator and property accessor classes to be used_ -- * _For identifiers to be generated, still use a final field in combination with an all-arguments persistence constructor (preferred) or a `with…` method_ -- @@ -307,14 +307,14 @@ data class Person(val id: String, val name: String) ---- ==== -The class above compiles to a typical class with an explicit constructor.We can customize this class by adding another constructor and annotate it with `@PersistenceConstructor` to indicate a constructor preference: +The class above compiles to a typical class with an explicit constructor.We can customize this class by adding another constructor and annotate it with `@PersistenceCreator` to indicate a constructor preference: ==== [source,kotlin] ---- data class Person(var id: String, val name: String) { - @PersistenceConstructor + @PersistenceCreator constructor(id: String) : this(id, "unknown") } ---- diff --git a/src/main/java/org/springframework/data/annotation/FactoryMethod.java b/src/main/java/org/springframework/data/annotation/FactoryMethod.java deleted file mode 100644 index 9bccfe565..000000000 --- a/src/main/java/org/springframework/data/annotation/FactoryMethod.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation to declare a {@code static} method as factory method for class instantiation. - * - * @author Mark Paluch - * @since 3.0 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) -@EntityCreatorAnnotation -public @interface FactoryMethod { -} diff --git a/src/main/java/org/springframework/data/annotation/PersistenceConstructor.java b/src/main/java/org/springframework/data/annotation/PersistenceConstructor.java index a44afb790..e69abab73 100644 --- a/src/main/java/org/springframework/data/annotation/PersistenceConstructor.java +++ b/src/main/java/org/springframework/data/annotation/PersistenceConstructor.java @@ -25,9 +25,11 @@ import java.lang.annotation.Target; * * @author Jon Brisbin * @author Mark Paluch + * @author Oliver Drotbohm + * @deprecated in favor of {@link PersistenceCreator} since 3.0, to be removed in 3.1 */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE }) -@EntityCreatorAnnotation -public @interface PersistenceConstructor { -} +@PersistenceCreator +@Deprecated +public @interface PersistenceConstructor {} diff --git a/src/main/java/org/springframework/data/annotation/EntityCreatorAnnotation.java b/src/main/java/org/springframework/data/annotation/PersistenceCreator.java similarity index 82% rename from src/main/java/org/springframework/data/annotation/EntityCreatorAnnotation.java rename to src/main/java/org/springframework/data/annotation/PersistenceCreator.java index d1132955c..310fccf4d 100644 --- a/src/main/java/org/springframework/data/annotation/EntityCreatorAnnotation.java +++ b/src/main/java/org/springframework/data/annotation/PersistenceCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2021 the original author or authors. + * Copyright 2011-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,9 @@ import java.lang.annotation.Target; * Marker annotation to declare a constructor or factory method annotation as factory/preferred constructor annotation. * * @author Mark Paluch + * @author Oliver Drotbohm * @since 3.0 */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.ANNOTATION_TYPE }) -public @interface EntityCreatorAnnotation { -} +@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +public @interface PersistenceCreator {} diff --git a/src/main/java/org/springframework/data/mapping/FactoryMethod.java b/src/main/java/org/springframework/data/mapping/FactoryMethod.java index f636f7bd3..e9781b7e0 100644 --- a/src/main/java/org/springframework/data/mapping/FactoryMethod.java +++ b/src/main/java/org/springframework/data/mapping/FactoryMethod.java @@ -26,7 +26,7 @@ import org.springframework.util.ReflectionUtils; * @author Mark Paluch * @since 3.0 */ -public final class FactoryMethod> extends EntityCreatorMetadataSupport { +public final class FactoryMethod> extends InstanceCreatorMetadataSupport { /** * Creates a new {@link FactoryMethod} from the given {@link Constructor} and {@link Parameter}s. @@ -49,5 +49,4 @@ public final class FactoryMethod> extends Ent public Method getFactoryMethod() { return (Method) getExecutable(); } - } diff --git a/src/main/java/org/springframework/data/mapping/EntityCreatorMetadata.java b/src/main/java/org/springframework/data/mapping/InstanceCreatorMetadata.java similarity index 86% rename from src/main/java/org/springframework/data/mapping/EntityCreatorMetadata.java rename to src/main/java/org/springframework/data/mapping/InstanceCreatorMetadata.java index bdb3a41b0..460b0e70c 100644 --- a/src/main/java/org/springframework/data/mapping/EntityCreatorMetadata.java +++ b/src/main/java/org/springframework/data/mapping/InstanceCreatorMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,13 @@ package org.springframework.data.mapping; import java.util.List; /** - * Metadata describing a mechanism to create an entity instance. + * Metadata describing a mechanism to create instances of persistent types. * * @author Mark Paluch + * @author Oliver Drotbohm * @since 3.0 */ -public interface EntityCreatorMetadata

> { +public interface InstanceCreatorMetadata

> { /** * Check whether the given {@link PersistentProperty} is being used as creator parameter. diff --git a/src/main/java/org/springframework/data/mapping/EntityCreatorMetadataSupport.java b/src/main/java/org/springframework/data/mapping/InstanceCreatorMetadataSupport.java similarity index 87% rename from src/main/java/org/springframework/data/mapping/EntityCreatorMetadataSupport.java rename to src/main/java/org/springframework/data/mapping/InstanceCreatorMetadataSupport.java index f4105f058..b53c6784f 100644 --- a/src/main/java/org/springframework/data/mapping/EntityCreatorMetadataSupport.java +++ b/src/main/java/org/springframework/data/mapping/InstanceCreatorMetadataSupport.java @@ -28,22 +28,23 @@ import org.springframework.util.Assert; * persistent data to objects. * * @author Mark Paluch + * @author Oliver Drotbohm * @since 3.0 */ -class EntityCreatorMetadataSupport> implements EntityCreatorMetadata

{ +class InstanceCreatorMetadataSupport> implements InstanceCreatorMetadata

{ private final Executable executable; private final List> parameters; private final Map, Boolean> isPropertyParameterCache = new ConcurrentHashMap<>(); /** - * Creates a new {@link EntityCreatorMetadataSupport} from the given {@link Executable} and {@link Parameter}s. + * Creates a new {@link InstanceCreatorMetadataSupport} from the given {@link Executable} and {@link Parameter}s. * * @param executable must not be {@literal null}. * @param parameters must not be {@literal null}. */ @SafeVarargs - public EntityCreatorMetadataSupport(Executable executable, Parameter... parameters) { + public InstanceCreatorMetadataSupport(Executable executable, Parameter... parameters) { Assert.notNull(executable, "Executable must not be null!"); Assert.notNull(parameters, "Parameters must not be null!"); @@ -72,7 +73,7 @@ class EntityCreatorMetadataSupport> implement /** * Returns whether the given {@link PersistentProperty} is referenced in a creator argument of the - * {@link PersistentEntity} backing this {@link EntityCreatorMetadataSupport}. + * {@link PersistentEntity} backing this {@link InstanceCreatorMetadataSupport}. *

* Results of this call are cached and reused on the next invocation. Calling this method for a * {@link PersistentProperty} that was not yet added to its owning {@link PersistentEntity} will capture that state diff --git a/src/main/java/org/springframework/data/mapping/PersistentEntity.java b/src/main/java/org/springframework/data/mapping/PersistentEntity.java index c5b641922..41b27db65 100644 --- a/src/main/java/org/springframework/data/mapping/PersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/PersistentEntity.java @@ -49,14 +49,14 @@ public interface PersistentEntity> extends It * indicates that the instantiation of the object of that persistent entity is done through either a customer * {@link org.springframework.data.mapping.model.EntityInstantiator} or handled by custom conversion * mechanisms entirely. - * @deprecated since 3.0, use {@link #getEntityCreator()}. + * @deprecated since 3.0, use {@link #getInstanceCreatorMetadata()}. */ @Nullable @Deprecated PreferredConstructor getPersistenceConstructor(); /** - * Returns the {@link EntityCreatorMetadata} to be used to instantiate objects of this {@link PersistentEntity}. + * Returns the {@link InstanceCreatorMetadata} to be used to instantiate objects of this {@link PersistentEntity}. * * @return {@literal null} in case no suitable creation mechanism for automatic construction can be found. This * usually indicates that the instantiation of the object of that persistent entity is done through either a @@ -65,7 +65,7 @@ public interface PersistentEntity> extends It * @since 3.0 */ @Nullable - EntityCreatorMetadata

getEntityCreator(); + InstanceCreatorMetadata

getInstanceCreatorMetadata(); /** * Returns whether the given {@link PersistentProperty} is referred to by a constructor argument of the diff --git a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java index 7b70501d7..bddb6b6e1 100644 --- a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java +++ b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java @@ -35,7 +35,7 @@ import org.springframework.util.ReflectionUtils; * @author Myeonghyeon Lee * @author Xeno Amess */ -public final class PreferredConstructor> extends EntityCreatorMetadataSupport { +public final class PreferredConstructor> extends InstanceCreatorMetadataSupport { private final List> parameters; diff --git a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java index 972204fb7..19af8221e 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -17,16 +17,7 @@ package org.springframework.data.mapping.model; import java.io.Serializable; import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import java.util.stream.Collectors; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -63,7 +54,7 @@ public class BasicPersistentEntity> implement private static final String TYPE_MISMATCH = "Target bean of type %s is not of type of the persistent entity (%s)!"; - private final @Nullable EntityCreatorMetadata

creator; + private final @Nullable InstanceCreatorMetadata

creator; private final TypeInformation information; private final List

properties; private final List

persistentPropertiesCache; @@ -109,7 +100,7 @@ public class BasicPersistentEntity> implement this.properties = new ArrayList<>(); this.persistentPropertiesCache = new ArrayList<>(); this.comparator = comparator; - this.creator = EntityCreatorMetadataDiscoverer.discover(this); + this.creator = InstanceCreatorMetadataDiscoverer.discover(this); this.associations = comparator == null ? new HashSet<>() : new TreeSet<>(new AssociationComparator<>(comparator)); this.propertyCache = new HashMap<>(16, 1f); @@ -129,12 +120,14 @@ public class BasicPersistentEntity> implement @Nullable @Override + @SuppressWarnings("unchecked") public PreferredConstructor getPersistenceConstructor() { return creator instanceof PreferredConstructor ? (PreferredConstructor) creator : null; } + @Nullable @Override - public EntityCreatorMetadata

getEntityCreator() { + public InstanceCreatorMetadata

getInstanceCreatorMetadata() { return creator; } diff --git a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiator.java b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiator.java index 9c46ade01..de53b8ebf 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiator.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiator.java @@ -25,7 +25,6 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.asm.ClassWriter; import org.springframework.asm.MethodVisitor; import org.springframework.asm.Opcodes; @@ -33,8 +32,8 @@ import org.springframework.asm.Type; import org.springframework.beans.BeanInstantiationException; import org.springframework.cglib.core.ReflectUtils; import org.springframework.core.NativeDetector; -import org.springframework.data.mapping.EntityCreatorMetadata; import org.springframework.data.mapping.FactoryMethod; +import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -159,7 +158,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { */ protected EntityInstantiator doCreateEntityInstantiator(PersistentEntity entity) { return new EntityInstantiatorAdapter( - createObjectInstantiator(entity, entity.getEntityCreator())); + createObjectInstantiator(entity, entity.getInstanceCreatorMetadata())); } /** @@ -187,20 +186,20 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { return true; } - var entityCreator = entity.getEntityCreator(); + var creatorMetadata = entity.getInstanceCreatorMetadata(); - if (entityCreator == null) { + if (creatorMetadata == null) { return true; } - if (entityCreator instanceof PreferredConstructor persistenceConstructor) { + if (creatorMetadata instanceof PreferredConstructor persistenceConstructor) { if (Modifier.isPrivate(persistenceConstructor.getConstructor().getModifiers())) { return true; } } - if (entityCreator instanceof FactoryMethod factoryMethod) { + if (creatorMetadata instanceof FactoryMethod factoryMethod) { if (Modifier.isPrivate(factoryMethod.getFactoryMethod().getModifiers())) { return true; @@ -227,7 +226,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { /** * Creates a dynamically generated {@link ObjectInstantiator} for the given {@link PersistentEntity} and - * {@link EntityCreatorMetadata}. There will always be exactly one {@link ObjectInstantiator} instance per + * {@link InstanceCreatorMetadata}. There will always be exactly one {@link ObjectInstantiator} instance per * {@link PersistentEntity}. * * @param entity @@ -235,7 +234,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { * @return */ ObjectInstantiator createObjectInstantiator(PersistentEntity entity, - @Nullable EntityCreatorMetadata constructor) { + @Nullable InstanceCreatorMetadata constructor) { try { return (ObjectInstantiator) this.generator.generateCustomInstantiatorClass(entity, constructor).newInstance(); @@ -269,7 +268,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { public , P extends PersistentProperty

> T createInstance(E entity, ParameterValueProvider

provider) { - var params = extractInvocationArguments(entity.getEntityCreator(), provider); + var params = extractInvocationArguments(entity.getInstanceCreatorMetadata(), provider); try { return (T) instantiator.newInstance(params); @@ -287,7 +286,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { * @return */ static

, T> Object[] extractInvocationArguments( - @Nullable EntityCreatorMetadata

constructor, ParameterValueProvider

provider) { + @Nullable InstanceCreatorMetadata

constructor, ParameterValueProvider

provider) { if (constructor == null || !constructor.hasParameters()) { return allocateArguments(0); @@ -336,7 +335,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { public , P extends PersistentProperty

> T createInstance(E entity, ParameterValueProvider

provider) { - var params = extractInvocationArguments(entity.getEntityCreator(), provider); + var params = extractInvocationArguments(entity.getInstanceCreatorMetadata(), provider); throw new MappingInstantiationException(entity, Arrays.asList(params), new BeanInstantiationException(typeToCreate, "Class is abstract")); @@ -400,7 +399,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { * @return */ public Class generateCustomInstantiatorClass(PersistentEntity entity, - @Nullable EntityCreatorMetadata constructor) { + @Nullable InstanceCreatorMetadata constructor) { var className = generateClassName(entity); var type = entity.getType(); @@ -441,7 +440,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { * @return */ public byte[] generateBytecode(String internalClassName, PersistentEntity entity, - @Nullable EntityCreatorMetadata entityCreator) { + @Nullable InstanceCreatorMetadata entityCreator) { var cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); @@ -476,7 +475,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator { * @param entityCreator */ private void visitCreateMethod(ClassWriter cw, PersistentEntity entity, - @Nullable EntityCreatorMetadata entityCreator) { + @Nullable InstanceCreatorMetadata entityCreator) { var entityTypeResourcePath = Type.getInternalName(entity.getType()); diff --git a/src/main/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscoverer.java b/src/main/java/org/springframework/data/mapping/model/InstanceCreatorMetadataDiscoverer.java similarity index 85% rename from src/main/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscoverer.java rename to src/main/java/org/springframework/data/mapping/model/InstanceCreatorMetadataDiscoverer.java index 9a9713374..0beffc14e 100644 --- a/src/main/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscoverer.java +++ b/src/main/java/org/springframework/data/mapping/model/InstanceCreatorMetadataDiscoverer.java @@ -25,8 +25,8 @@ import java.util.List; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.data.annotation.EntityCreatorAnnotation; -import org.springframework.data.mapping.EntityCreatorMetadata; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.FactoryMethod; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.Parameter; @@ -40,7 +40,7 @@ import org.springframework.lang.Nullable; * @author Mark Paluch * @since 3.0 */ -class EntityCreatorMetadataDiscoverer { +class InstanceCreatorMetadataDiscoverer { private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer(); @@ -53,13 +53,13 @@ class EntityCreatorMetadataDiscoverer { * @return */ @Nullable - public static > EntityCreatorMetadata

discover(PersistentEntity entity) { + public static > InstanceCreatorMetadata

discover(PersistentEntity entity) { var declaredConstructors = entity.getType().getDeclaredConstructors(); var declaredMethods = entity.getType().getDeclaredMethods(); - var hasAnnotatedFactoryMethod = findAnnotation(EntityCreatorAnnotation.class, declaredMethods); - var hasAnnotatedConstructor = findAnnotation(EntityCreatorAnnotation.class, declaredConstructors); + var hasAnnotatedFactoryMethod = findAnnotation(PersistenceCreator.class, declaredMethods); + var hasAnnotatedConstructor = findAnnotation(PersistenceCreator.class, declaredConstructors); if (hasAnnotatedConstructor && hasAnnotatedFactoryMethod) { throw new MappingException( @@ -92,7 +92,7 @@ class EntityCreatorMetadataDiscoverer { continue; } - if (findAnnotation(EntityCreatorAnnotation.class, method)) { + if (findAnnotation(PersistenceCreator.class, method)) { candidates.add(method); } } @@ -124,11 +124,11 @@ class EntityCreatorMetadataDiscoverer { private static void validateMethod(Method method) { - if (MergedAnnotations.from(method).isPresent(EntityCreatorAnnotation.class)) { + if (MergedAnnotations.from(method).isPresent(PersistenceCreator.class)) { if (!Modifier.isStatic(method.getModifiers())) { throw new MappingException( - "@Factory can only be used on static methods. Offending method: %s".formatted(method)); + "@PersistenceCreator can only be used on static methods. Offending method: %s".formatted(method)); } } } diff --git a/src/main/java/org/springframework/data/mapping/model/InstantiationAwarePropertyAccessor.java b/src/main/java/org/springframework/data/mapping/model/InstantiationAwarePropertyAccessor.java index 66a6685e1..f25f69811 100644 --- a/src/main/java/org/springframework/data/mapping/model/InstantiationAwarePropertyAccessor.java +++ b/src/main/java/org/springframework/data/mapping/model/InstantiationAwarePropertyAccessor.java @@ -81,7 +81,7 @@ public class InstantiationAwarePropertyAccessor implements PersistentProperty return; } - var creator = owner.getEntityCreator(); + var creator = owner.getInstanceCreatorMetadata(); if (creator == null) { throw new IllegalStateException(String.format(NO_SETTER_OR_CONSTRUCTOR, property.getName(), owner.getType())); diff --git a/src/main/java/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiator.java b/src/main/java/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiator.java index ed65591fa..fdeac60d9 100644 --- a/src/main/java/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiator.java +++ b/src/main/java/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiator.java @@ -24,7 +24,7 @@ import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; -import org.springframework.data.mapping.EntityCreatorMetadata; +import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -46,7 +46,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta @Override protected EntityInstantiator doCreateEntityInstantiator(PersistentEntity entity) { - var creator = entity.getEntityCreator(); + var creator = entity.getInstanceCreatorMetadata(); if (KotlinReflectionUtils.isSupportedKotlinClass(entity.getType()) && creator instanceof PreferredConstructor constructor) { @@ -80,9 +80,9 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta DefaultingKotlinConstructorResolver(PersistentEntity entity) { var hit = resolveDefaultConstructor(entity); - var creator = entity.getEntityCreator(); + var creator = entity.getInstanceCreatorMetadata(); - if (hit != null && creator instanceof PreferredConstructor persistenceConstructor) { + if ((hit != null) && creator instanceof PreferredConstructor persistenceConstructor) { this.defaultConstructor = new PreferredConstructor<>(hit, persistenceConstructor.getParameters().toArray(new Parameter[0])); } else { @@ -93,7 +93,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta @Nullable private static Constructor resolveDefaultConstructor(PersistentEntity entity) { - if (!(entity.getEntityCreator()instanceof PreferredConstructor persistenceConstructor)) { + if (!(entity.getInstanceCreatorMetadata() instanceof PreferredConstructor persistenceConstructor)) { return null; } @@ -112,7 +112,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta var syntheticParameters = KotlinDefaultMask.getMaskCount(constructor.getParameterCount()) + /* DefaultConstructorMarker */ 1; - if (constructor.getParameterCount() + syntheticParameters != candidate.getParameterCount()) { + if ((constructor.getParameterCount() + syntheticParameters) != candidate.getParameterCount()) { continue; } @@ -191,7 +191,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta public , P extends PersistentProperty

> T createInstance(E entity, ParameterValueProvider

provider) { - var params = extractInvocationArguments(entity.getEntityCreator(), provider); + var params = extractInvocationArguments(entity.getInstanceCreatorMetadata(), provider); try { return (T) instantiator.newInstance(params); @@ -201,7 +201,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta } private

, T> Object[] extractInvocationArguments( - @Nullable EntityCreatorMetadata

entityCreator, ParameterValueProvider

provider) { + @Nullable InstanceCreatorMetadata

entityCreator, ParameterValueProvider

provider) { if (entityCreator == null) { throw new IllegalArgumentException("EntityCreator must not be null!"); @@ -227,7 +227,7 @@ class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEntityInsta var parameter = parameters.get(index); var type = parameter.getType().getType(); - if (it.isOptional() && params[index] == null) { + if (it.isOptional() && (params[index] == null)) { if (type.isPrimitive()) { // apply primitive defaulting to prevent NPE on primitive downcast diff --git a/src/main/java/org/springframework/data/mapping/model/MappingInstantiationException.java b/src/main/java/org/springframework/data/mapping/model/MappingInstantiationException.java index 85d89f7af..e606ebc4d 100644 --- a/src/main/java/org/springframework/data/mapping/model/MappingInstantiationException.java +++ b/src/main/java/org/springframework/data/mapping/model/MappingInstantiationException.java @@ -22,8 +22,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import org.springframework.data.mapping.EntityCreatorMetadata; import org.springframework.data.mapping.FactoryMethod; +import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.util.KotlinReflectionUtils; @@ -44,7 +44,7 @@ public class MappingInstantiationException extends RuntimeException { private static final String TEXT_TEMPLATE = "Failed to instantiate %s using constructor %s with arguments %s"; private final Class entityType; - private final EntityCreatorMetadata entityCreator; + private final InstanceCreatorMetadata entityCreator; private final List constructorArguments; /** @@ -75,7 +75,7 @@ public class MappingInstantiationException extends RuntimeException { super(buildExceptionMessage(entity, arguments, message), cause); this.entityType = entity.map(PersistentEntity::getType).orElse(null); - this.entityCreator = entity.map(PersistentEntity::getEntityCreator).orElse(null); + this.entityCreator = entity.map(PersistentEntity::getInstanceCreatorMetadata).orElse(null); this.constructorArguments = arguments; } @@ -84,7 +84,7 @@ public class MappingInstantiationException extends RuntimeException { return entity.map(it -> { - Optional> constructor = Optional.ofNullable(it.getEntityCreator()); + Optional> constructor = Optional.ofNullable(it.getInstanceCreatorMetadata()); List toStringArgs = new ArrayList<>(arguments.size()); for (var o : arguments) { @@ -98,7 +98,7 @@ public class MappingInstantiationException extends RuntimeException { }).orElse(defaultMessage); } - private static String toString(EntityCreatorMetadata creator) { + private static String toString(InstanceCreatorMetadata creator) { if (creator instanceof PreferredConstructor c) { return toString(c); @@ -170,7 +170,7 @@ public class MappingInstantiationException extends RuntimeException { * @return the entity creator * @since 3.0 */ - public Optional> getEntityCreator() { + public Optional> getEntityCreator() { return Optional.ofNullable(entityCreator); } diff --git a/src/main/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProvider.java b/src/main/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProvider.java index 05767a284..0bf06cef1 100644 --- a/src/main/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProvider.java +++ b/src/main/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProvider.java @@ -47,10 +47,10 @@ public class PersistentEntityParameterValueProvider

T getParameterValue(Parameter parameter) { - var creator = entity.getEntityCreator(); + var creator = entity.getInstanceCreatorMetadata(); - if (creator.isParentParameter(parameter)) { - return (T) parent; + if (creator != null && creator.isParentParameter(parameter)) { + return (T) parent; } var name = parameter.getName(); diff --git a/src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java b/src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java index fe1ae2e48..7dd88d054 100644 --- a/src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java +++ b/src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java @@ -27,7 +27,7 @@ import java.util.List; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.annotation.EntityCreatorAnnotation; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -111,7 +111,7 @@ public interface PreferredConstructorDiscoverer !it.isSynthetic()) // Synthetic constructors should not be considered - .filter(it -> AnnotationUtils.findAnnotation(it, EntityCreatorAnnotation.class) != null) // Explicitly - // defined - // constructor - // trumps - // all + // Explicitly defined creator trumps all + .filter(it -> AnnotationUtils.findAnnotation(it, PersistenceCreator.class) != null) .map(it -> buildPreferredConstructor(it, type, entity)) // .findFirst() // .orElseGet(() -> { diff --git a/src/main/java/org/springframework/data/mapping/model/ReflectionEntityInstantiator.java b/src/main/java/org/springframework/data/mapping/model/ReflectionEntityInstantiator.java index 581616bd4..49851e58b 100644 --- a/src/main/java/org/springframework/data/mapping/model/ReflectionEntityInstantiator.java +++ b/src/main/java/org/springframework/data/mapping/model/ReflectionEntityInstantiator.java @@ -46,7 +46,7 @@ enum ReflectionEntityInstantiator implements EntityInstantiator { public , P extends PersistentProperty

> T createInstance(E entity, ParameterValueProvider

provider) { - var creator = entity.getEntityCreator(); + var creator = entity.getInstanceCreatorMetadata(); if (creator == null) { return instantiateClass(entity); @@ -59,7 +59,7 @@ enum ReflectionEntityInstantiator implements EntityInstantiator { params[i++] = provider.getParameterValue(parameter); } - if (creator instanceof FactoryMethod method) { + if (creator instanceof FactoryMethod method) { try { var t = (T) ReflectionUtils.invokeMethod(method.getFactoryMethod(), null, params); @@ -80,6 +80,7 @@ enum ReflectionEntityInstantiator implements EntityInstantiator { } } + @SuppressWarnings("unchecked") private , P extends PersistentProperty

> T instantiateClass( E entity) { diff --git a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java index 59eb7f229..d99bfa31d 100755 --- a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java @@ -32,8 +32,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; - -import org.springframework.data.annotation.FactoryMethod; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.classloadersupport.HidingClassLoader; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; @@ -84,7 +83,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

PreferredConstructor constructor = PreferredConstructorDiscoverer.discover(Foo.class); doReturn(Foo.class).when(entity).getType(); - doReturn(constructor).when(entity).getEntityCreator(); + doReturn(constructor).when(entity).getInstanceCreatorMetadata(); assertThat(instance.createInstance(entity, provider)).isInstanceOf(Foo.class); @@ -106,7 +105,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

void createsInnerClassInstanceCorrectly() { var entity = new BasicPersistentEntity(from(Inner.class)); - assertThat(entity.getEntityCreator()).satisfies(constructor -> { + assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> { var parameter = constructor.getParameters().iterator().next(); @@ -226,7 +225,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjCtorDefault.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjCtorDefault.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); IntStream.range(0, 2) .forEach(i -> assertThat(this.instance.createInstance(entity, provider)).isInstanceOf(ObjCtorDefault.class)); @@ -237,7 +236,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjCtorNoArgs.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjCtorNoArgs.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); IntStream.range(0, 2).forEach(i -> { @@ -256,7 +255,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjCtor1ParamString.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjCtor1ParamString.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); doReturn("FOO").when(provider).getParameterValue(any()); IntStream.range(0, 2).forEach(i -> { @@ -274,7 +273,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjCtor2ParamStringString.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjCtor2ParamStringString.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); IntStream.range(0, 2).forEach(i -> { @@ -294,7 +293,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjectCtor1ParamInt.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjectCtor1ParamInt.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); IntStream.range(0, 2).forEach(i -> { @@ -312,7 +311,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjectCtor1ParamInt.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjectCtor1ParamInt.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); assertThatThrownBy(() -> this.instance.createInstance(entity, provider)) // .hasCauseInstanceOf(IllegalArgumentException.class); @@ -324,7 +323,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(ObjectCtor7ParamsString5IntsString.class).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(ObjectCtor7ParamsString5IntsString.class))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); IntStream.range(0, 2).forEach(i -> { @@ -444,7 +443,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

doReturn(type).when(entity).getType(); doReturn(PreferredConstructorDiscoverer.discover(type))// - .when(entity).getEntityCreator(); + .when(entity).getInstanceCreatorMetadata(); } static class Foo { @@ -472,7 +471,7 @@ class ClassGeneratingEntityInstantiatorUnitTests

this.name = name; } - @FactoryMethod + @PersistenceCreator public static WithFactoryMethod create(Long id, String name) { return new WithFactoryMethod(id, "Hello " + name); } diff --git a/src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java b/src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java index 8ffc8b659..9b5dea5e7 100644 --- a/src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java @@ -18,14 +18,13 @@ package org.springframework.data.mapping.model; import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Test; - -import org.springframework.data.annotation.FactoryMethod; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.util.ClassTypeInformation; /** - * Unit tests for {@link EntityCreatorMetadataDiscoverer}. + * Unit tests for {@link InstanceCreatorMetadataDiscoverer}. * * @author Mark Paluch */ @@ -35,7 +34,7 @@ class EntityCreatorMetadataDiscovererUnitTests { void shouldDiscoverAnnotatedFactoryMethod() { var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(FactoryMethodsPerson.class)); - var creator = EntityCreatorMetadataDiscoverer.discover(entity); + var creator = InstanceCreatorMetadataDiscoverer.discover(entity); assertThat(creator).isInstanceOf(org.springframework.data.mapping.FactoryMethod.class); assertThat(((org.springframework.data.mapping.FactoryMethod) creator).getFactoryMethod().getParameterCount()) @@ -46,7 +45,7 @@ class EntityCreatorMetadataDiscovererUnitTests { void shouldDiscoverAnnotatedConstructor() { var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(ConstructorPerson.class)); - var creator = EntityCreatorMetadataDiscoverer.discover(entity); + var creator = InstanceCreatorMetadataDiscoverer.discover(entity); assertThat(creator).isInstanceOf(PreferredConstructor.class); } @@ -55,7 +54,7 @@ class EntityCreatorMetadataDiscovererUnitTests { void shouldDiscoverDefaultConstructor() { var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(Person.class)); - var creator = EntityCreatorMetadataDiscoverer.discover(entity); + var creator = InstanceCreatorMetadataDiscoverer.discover(entity); assertThat(creator).isInstanceOf(PreferredConstructor.class); } @@ -79,7 +78,7 @@ class EntityCreatorMetadataDiscovererUnitTests { static class NonStaticFactoryMethod { - @FactoryMethod + @PersistenceCreator public ConstructorPerson of(String firstname, String lastname) { return new ConstructorPerson(firstname, lastname); } @@ -99,7 +98,7 @@ class EntityCreatorMetadataDiscovererUnitTests { return new FactoryMethodsPerson(firstname, "unknown"); } - @FactoryMethod + @PersistenceCreator public static FactoryMethodsPerson of(String firstname, String lastname) { return new FactoryMethodsPerson(firstname, lastname); } diff --git a/src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java b/src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java index e0ec5eec4..407ca0294 100644 --- a/src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java @@ -18,8 +18,7 @@ package org.springframework.data.mapping.model; import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Test; - -import org.springframework.data.annotation.FactoryMethod; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.mapping.Parameter; import org.springframework.data.util.ClassTypeInformation; @@ -67,7 +66,7 @@ class FactoryMethodUnitTests { this.lastname = lastname; } - @FactoryMethod + @PersistenceCreator public static FactoryPerson of(String firstname, String lastname) { return new FactoryPerson(firstname, "Mr. " + lastname); } diff --git a/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java b/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java index 5fd30c297..02b114846 100755 --- a/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java @@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -55,7 +54,7 @@ class PersistentEntityParameterValueProviderUnitTests

{ + assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> { var iterator = constructor.getParameters().iterator(); ParameterValueProvider

provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider, @@ -74,7 +73,7 @@ class PersistentEntityParameterValueProviderUnitTests

provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider, Optional.of(property)); - assertThat(entity.getEntityCreator()) + assertThat(entity.getInstanceCreatorMetadata()) .satisfies(constructor -> assertThatExceptionOfType(MappingException.class)// .isThrownBy(() -> provider.getParameterValue(constructor.getParameters().iterator().next()))// .withMessageContaining("bar")// diff --git a/src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java b/src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java index 51bb159cf..18c7ede10 100755 --- a/src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java @@ -29,7 +29,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -69,7 +68,7 @@ class ReflectionEntityInstantiatorUnitTests

> { PreferredConstructor constructor = PreferredConstructorDiscoverer.discover(Foo.class); - doReturn(constructor).when(entity).getEntityCreator(); + doReturn(constructor).when(entity).getInstanceCreatorMetadata(); var instance = INSTANCE.createInstance(entity, provider); @@ -92,7 +91,7 @@ class ReflectionEntityInstantiatorUnitTests

> { void createsInnerClassInstanceCorrectly() { var entity = new BasicPersistentEntity(from(Inner.class)); - assertThat(entity.getEntityCreator()).satisfies(it -> { + assertThat(entity.getInstanceCreatorMetadata()).satisfies(it -> { var parameter = it.getParameters().iterator().next(); diff --git a/src/test/kotlin/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiatorUnitTests.kt b/src/test/kotlin/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiatorUnitTests.kt index 3b29fb7ff..f0afb5d10 100644 --- a/src/test/kotlin/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiatorUnitTests.kt +++ b/src/test/kotlin/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiatorUnitTests.kt @@ -45,7 +45,7 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { ) every { provider.getParameterValue(any()) }.returnsMany("Walter", "White") - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor every { entity.type } returns constructor.constructor.declaringClass every { entity.typeInformation } returns mockk() @@ -73,7 +73,7 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { null, "Walter", null, "Junior", null ) - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor every { entity.type } returns constructor.constructor.declaringClass every { entity.typeInformation } returns mockk() @@ -97,7 +97,7 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { ) every { provider.getParameterValue(any()) } returns null - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor every { entity.type } returns constructor.constructor.declaringClass every { entity.typeInformation } returns mockk() @@ -130,7 +130,7 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { every { provider.getParameterValue(any()) } returns null every { provider.getParameterValue(any()) } returns null every { provider.getParameterValue(any()) } returns null - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor every { entity.type } returns constructor.constructor.declaringClass every { entity.typeInformation } returns mockk() @@ -156,7 +156,7 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { ) every { provider.getParameterValue(any()) } returns "Walter" - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor every { entity.type } returns constructor.constructor.declaringClass every { entity.typeInformation } returns mockk() diff --git a/src/test/kotlin/org/springframework/data/mapping/model/ReflectionEntityInstantiatorDataClassUnitTests.kt b/src/test/kotlin/org/springframework/data/mapping/model/ReflectionEntityInstantiatorDataClassUnitTests.kt index 217518e88..35d736e2f 100644 --- a/src/test/kotlin/org/springframework/data/mapping/model/ReflectionEntityInstantiatorDataClassUnitTests.kt +++ b/src/test/kotlin/org/springframework/data/mapping/model/ReflectionEntityInstantiatorDataClassUnitTests.kt @@ -43,7 +43,7 @@ class ReflectionEntityInstantiatorDataClassUnitTests { ) every { provider.getParameterValue(any()) }.returnsMany("Walter", "White") - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor val instance: Contact = ReflectionEntityInstantiator.INSTANCE.createInstance(entity, provider) @@ -63,7 +63,7 @@ class ReflectionEntityInstantiatorDataClassUnitTests { ) every { provider.getParameterValue(any()) }.returnsMany("Walter", null) - every { entity.entityCreator } returns constructor + every { entity.instanceCreatorMetadata } returns constructor val instance: ContactWithDefaulting = ReflectionEntityInstantiator.INSTANCE.createInstance(entity, provider)