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 ec0c0d3cb2
commit 1e38b4c6ba
25 changed files with 117 additions and 149 deletions

View File

@@ -32,7 +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;
@@ -83,7 +83,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
PreferredConstructor<Foo, P> 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);
@@ -105,7 +105,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
void createsInnerClassInstanceCorrectly() {
BasicPersistentEntity<Inner, P> entity = new BasicPersistentEntity<Inner, P>(from(Inner.class));
assertThat(entity.getEntityCreator()).satisfies(constructor -> {
assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> {
Parameter<Object, P> parameter = constructor.getParameters().iterator().next();
@@ -225,7 +225,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
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));
@@ -236,7 +236,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
doReturn(ObjCtorNoArgs.class).when(entity).getType();
doReturn(PreferredConstructorDiscoverer.discover(ObjCtorNoArgs.class))//
.when(entity).getEntityCreator();
.when(entity).getInstanceCreatorMetadata();
IntStream.range(0, 2).forEach(i -> {
@@ -255,7 +255,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
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 -> {
@@ -273,7 +273,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
doReturn(ObjCtor2ParamStringString.class).when(entity).getType();
doReturn(PreferredConstructorDiscoverer.discover(ObjCtor2ParamStringString.class))//
.when(entity).getEntityCreator();
.when(entity).getInstanceCreatorMetadata();
IntStream.range(0, 2).forEach(i -> {
@@ -293,7 +293,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
doReturn(ObjectCtor1ParamInt.class).when(entity).getType();
doReturn(PreferredConstructorDiscoverer.discover(ObjectCtor1ParamInt.class))//
.when(entity).getEntityCreator();
.when(entity).getInstanceCreatorMetadata();
IntStream.range(0, 2).forEach(i -> {
@@ -311,7 +311,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
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);
@@ -323,7 +323,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
doReturn(ObjectCtor7ParamsString5IntsString.class).when(entity).getType();
doReturn(PreferredConstructorDiscoverer.discover(ObjectCtor7ParamsString5IntsString.class))//
.when(entity).getEntityCreator();
.when(entity).getInstanceCreatorMetadata();
IntStream.range(0, 2).forEach(i -> {
@@ -443,7 +443,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
doReturn(type).when(entity).getType();
doReturn(PreferredConstructorDiscoverer.discover(type))//
.when(entity).getEntityCreator();
.when(entity).getInstanceCreatorMetadata();
}
static class Foo {
@@ -471,7 +471,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
this.name = name;
}
@FactoryMethod
@PersistenceCreator
public static WithFactoryMethod create(Long id, String name) {
return new WithFactoryMethod(id, "Hello " + name);
}

View File

@@ -18,7 +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.mapping.PersistentEntity;
import org.springframework.data.util.ClassTypeInformation;
@@ -68,7 +68,7 @@ class FactoryMethodUnitTests {
this.lastname = lastname;
}
@FactoryMethod
@PersistenceCreator
public static FactoryPerson of(String firstname, String lastname) {
return new FactoryPerson(firstname, "Mr. " + lastname);
}

View File

@@ -18,26 +18,26 @@ 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.mapping.EntityCreatorMetadata;
import org.springframework.data.annotation.PersistenceCreator;
import org.springframework.data.mapping.InstanceCreatorMetadata;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentEntity;
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
*/
class EntityCreatorMetadataDiscovererUnitTests {
class InstanceCreatorMetadataDiscovererUnitTests {
@Test
void shouldDiscoverAnnotatedFactoryMethod() {
PersistentEntity<FactoryMethodsPerson, ?> entity = new BasicPersistentEntity<>(
ClassTypeInformation.from(FactoryMethodsPerson.class));
EntityCreatorMetadata<?> creator = EntityCreatorMetadataDiscoverer.discover(entity);
InstanceCreatorMetadata<?> creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(org.springframework.data.mapping.FactoryMethod.class);
assertThat(((org.springframework.data.mapping.FactoryMethod<?, ?>) creator).getFactoryMethod().getParameterCount())
@@ -49,7 +49,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
PersistentEntity<ConstructorPerson, ?> entity = new BasicPersistentEntity<>(
ClassTypeInformation.from(ConstructorPerson.class));
EntityCreatorMetadata<?> creator = EntityCreatorMetadataDiscoverer.discover(entity);
InstanceCreatorMetadata<?> creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(PreferredConstructor.class);
}
@@ -58,7 +58,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
void shouldDiscoverDefaultConstructor() {
PersistentEntity<Person, ?> entity = new BasicPersistentEntity<>(ClassTypeInformation.from(Person.class));
EntityCreatorMetadata<?> creator = EntityCreatorMetadataDiscoverer.discover(entity);
InstanceCreatorMetadata<?> creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(PreferredConstructor.class);
}
@@ -82,7 +82,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
static class NonStaticFactoryMethod {
@FactoryMethod
@PersistenceCreator
public ConstructorPerson of(String firstname, String lastname) {
return new ConstructorPerson(firstname, lastname);
}
@@ -102,7 +102,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
return new FactoryMethodsPerson(firstname, "unknown");
}
@FactoryMethod
@PersistenceCreator
public static FactoryMethodsPerson of(String firstname, String lastname) {
return new FactoryMethodsPerson(firstname, lastname);
}

View File

@@ -56,7 +56,7 @@ class PersistentEntityParameterValueProviderUnitTests<P extends PersistentProper
}
};
assertThat(entity.getEntityCreator()).satisfies(constructor -> {
assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> {
Iterator<Parameter<Object, P>> iterator = constructor.getParameters().iterator();
ParameterValueProvider<P> provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider,
@@ -75,7 +75,7 @@ class PersistentEntityParameterValueProviderUnitTests<P extends PersistentProper
ParameterValueProvider<P> 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")//

View File

@@ -69,7 +69,7 @@ class ReflectionEntityInstantiatorUnitTests<P extends PersistentProperty<P>> {
PreferredConstructor<Foo, P> constructor = PreferredConstructorDiscoverer.discover(Foo.class);
doReturn(constructor).when(entity).getEntityCreator();
doReturn(constructor).when(entity).getInstanceCreatorMetadata();
Object instance = INSTANCE.createInstance(entity, provider);
@@ -92,7 +92,7 @@ class ReflectionEntityInstantiatorUnitTests<P extends PersistentProperty<P>> {
void createsInnerClassInstanceCorrectly() {
BasicPersistentEntity<Inner, P> entity = new BasicPersistentEntity<Inner, P>(from(Inner.class));
assertThat(entity.getEntityCreator()).satisfies(it -> {
assertThat(entity.getInstanceCreatorMetadata()).satisfies(it -> {
Parameter<Object, P> parameter = it.getParameters().iterator().next();