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

@@ -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<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);
@@ -106,7 +105,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
void createsInnerClassInstanceCorrectly() {
var entity = new BasicPersistentEntity<Inner, P>(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<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));
@@ -237,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 -> {
@@ -256,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 -> {
@@ -274,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 -> {
@@ -294,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 -> {
@@ -312,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);
@@ -324,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 -> {
@@ -444,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 {
@@ -472,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,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);
}

View File

@@ -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);
}

View File

@@ -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<P extends PersistentProper
}
};
assertThat(entity.getEntityCreator()).satisfies(constructor -> {
assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> {
var iterator = constructor.getParameters().iterator();
ParameterValueProvider<P> provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider,
@@ -74,7 +73,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

@@ -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<P extends PersistentProperty<P>> {
PreferredConstructor<Foo, P> 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<P extends PersistentProperty<P>> {
void createsInnerClassInstanceCorrectly() {
var entity = new BasicPersistentEntity<Inner, P>(from(Inner.class));
assertThat(entity.getEntityCreator()).satisfies(it -> {
assertThat(entity.getInstanceCreatorMetadata()).satisfies(it -> {
var parameter = it.getParameters().iterator().next();