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.
This commit is contained in:
Oliver Drotbohm
2022-01-28 11:05:50 +01:00
parent c4a324e3cf
commit ac9f99fc54
25 changed files with 117 additions and 162 deletions

View File

@@ -26,7 +26,7 @@ import org.springframework.util.ReflectionUtils;
* @author Mark Paluch
* @since 3.0
*/
public final class FactoryMethod<T, P extends PersistentProperty<P>> extends EntityCreatorMetadataSupport<T, P> {
public final class FactoryMethod<T, P extends PersistentProperty<P>> extends InstanceCreatorMetadataSupport<T, P> {
/**
* Creates a new {@link FactoryMethod} from the given {@link Constructor} and {@link Parameter}s.
@@ -49,5 +49,4 @@ public final class FactoryMethod<T, P extends PersistentProperty<P>> extends Ent
public Method getFactoryMethod() {
return (Method) getExecutable();
}
}

View File

@@ -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<P extends PersistentProperty<P>> {
public interface InstanceCreatorMetadata<P extends PersistentProperty<P>> {
/**
* Check whether the given {@link PersistentProperty} is being used as creator parameter.

View File

@@ -28,22 +28,23 @@ import org.springframework.util.Assert;
* persistent data to objects.
*
* @author Mark Paluch
* @author Oliver Drotbohm
* @since 3.0
*/
class EntityCreatorMetadataSupport<T, P extends PersistentProperty<P>> implements EntityCreatorMetadata<P> {
class InstanceCreatorMetadataSupport<T, P extends PersistentProperty<P>> implements InstanceCreatorMetadata<P> {
private final Executable executable;
private final List<Parameter<Object, P>> parameters;
private final Map<PersistentProperty<?>, 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<Object, P>... parameters) {
public InstanceCreatorMetadataSupport(Executable executable, Parameter<Object, P>... parameters) {
Assert.notNull(executable, "Executable must not be null!");
Assert.notNull(parameters, "Parameters must not be null!");
@@ -72,7 +73,7 @@ class EntityCreatorMetadataSupport<T, P extends PersistentProperty<P>> 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}.
* <p>
* 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

View File

@@ -49,14 +49,14 @@ public interface PersistentEntity<T, P extends PersistentProperty<P>> 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<T, P> 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<T, P extends PersistentProperty<P>> extends It
* @since 3.0
*/
@Nullable
EntityCreatorMetadata<P> getEntityCreator();
InstanceCreatorMetadata<P> getInstanceCreatorMetadata();
/**
* Returns whether the given {@link PersistentProperty} is referred to by a constructor argument of the

View File

@@ -35,7 +35,7 @@ import org.springframework.util.ReflectionUtils;
* @author Myeonghyeon Lee
* @author Xeno Amess
*/
public final class PreferredConstructor<T, P extends PersistentProperty<P>> extends EntityCreatorMetadataSupport<T, P> {
public final class PreferredConstructor<T, P extends PersistentProperty<P>> extends InstanceCreatorMetadataSupport<T, P> {
private final List<Parameter<Object, P>> parameters;

View File

@@ -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<T, P extends PersistentProperty<P>> 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<P> creator;
private final @Nullable InstanceCreatorMetadata<P> creator;
private final TypeInformation<T> information;
private final List<P> properties;
private final List<P> persistentPropertiesCache;
@@ -109,7 +100,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> 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<T, P extends PersistentProperty<P>> implement
@Nullable
@Override
@SuppressWarnings("unchecked")
public PreferredConstructor<T, P> getPersistenceConstructor() {
return creator instanceof PreferredConstructor ? (PreferredConstructor<T, P>) creator : null;
}
@Nullable
@Override
public EntityCreatorMetadata<P> getEntityCreator() {
public InstanceCreatorMetadata<P> getInstanceCreatorMetadata() {
return creator;
}

View File

@@ -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 <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> 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 <P extends PersistentProperty<P>, T> Object[] extractInvocationArguments(
@Nullable EntityCreatorMetadata<P> constructor, ParameterValueProvider<P> provider) {
@Nullable InstanceCreatorMetadata<P> constructor, ParameterValueProvider<P> provider) {
if (constructor == null || !constructor.hasParameters()) {
return allocateArguments(0);
@@ -336,7 +335,7 @@ class ClassGeneratingEntityInstantiator implements EntityInstantiator {
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> 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());

View File

@@ -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 <T, P extends PersistentProperty<P>> EntityCreatorMetadata<P> discover(PersistentEntity<T, P> entity) {
public static <T, P extends PersistentProperty<P>> InstanceCreatorMetadata<P> discover(PersistentEntity<T, P> 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));
}
}
}

View File

@@ -81,7 +81,7 @@ public class InstantiationAwarePropertyAccessor<T> 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()));

View File

@@ -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 <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> 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 <P extends PersistentProperty<P>, T> Object[] extractInvocationArguments(
@Nullable EntityCreatorMetadata<P> entityCreator, ParameterValueProvider<P> provider) {
@Nullable InstanceCreatorMetadata<P> entityCreator, ParameterValueProvider<P> 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

View File

@@ -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<Object> 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<? extends EntityCreatorMetadata<?>> constructor = Optional.ofNullable(it.getEntityCreator());
Optional<? extends InstanceCreatorMetadata<?>> constructor = Optional.ofNullable(it.getInstanceCreatorMetadata());
List<String> 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<EntityCreatorMetadata<?>> getEntityCreator() {
public Optional<InstanceCreatorMetadata<?>> getEntityCreator() {
return Optional.ofNullable(entityCreator);
}

View File

@@ -47,10 +47,10 @@ public class PersistentEntityParameterValueProvider<P extends PersistentProperty
@SuppressWarnings("unchecked")
public <T> T getParameterValue(Parameter<T, P> 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();

View File

@@ -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<T, P extends PersistentProperty<
continue;
}
if (AnnotationUtils.findAnnotation(candidate, EntityCreatorAnnotation.class) != null) {
if (AnnotationUtils.findAnnotation(candidate, PersistenceCreator.class) != null) {
return buildPreferredConstructor(candidate, type, entity);
}
@@ -145,11 +145,8 @@ public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<
return Arrays.stream(rawOwningType.getDeclaredConstructors()) //
.filter(it -> !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(() -> {

View File

@@ -46,7 +46,7 @@ enum ReflectionEntityInstantiator implements EntityInstantiator {
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> 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 <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T instantiateClass(
E entity) {