Browse Source

Fix KotlinCopyMethod detection for single-association property classes.

KotlinCopyMethod.shouldUsePublicCopyMethod(…) now considers single-association arrangements. Also, the method now early exists if pre-conditions aren't met.

Closes #3131
pull/3136/head
Mark Paluch 2 years ago
parent
commit
1cdfb2e533
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 4
      src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java
  2. 22
      src/test/java/org/springframework/data/mapping/model/KotlinPropertyAccessorFactoryTests.java
  3. 15
      src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt

4
src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java

@ -38,6 +38,7 @@ import java.util.stream.Collectors; @@ -38,6 +38,7 @@ import java.util.stream.Collectors;
import org.springframework.core.ResolvableType;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.SimpleAssociationHandler;
import org.springframework.data.mapping.SimplePropertyHandler;
import org.springframework.data.util.KotlinReflectionUtils;
import org.springframework.util.Assert;
@ -158,8 +159,9 @@ class KotlinCopyMethod { @@ -158,8 +159,9 @@ class KotlinCopyMethod {
List<PersistentProperty<?>> persistentProperties = new ArrayList<>();
entity.doWithProperties((SimplePropertyHandler) persistentProperties::add);
entity.doWithAssociations((SimpleAssociationHandler) it -> persistentProperties.add(it.getInverse()));
if (persistentProperties.size() > 1) {
if (persistentProperties.size() != 1) {
return false;
}

22
src/test/java/org/springframework/data/mapping/model/KotlinPropertyAccessorFactoryTests.java

@ -25,6 +25,7 @@ import java.lang.reflect.Constructor; @@ -25,6 +25,7 @@ import java.lang.reflect.Constructor;
import java.util.function.Function;
import java.util.stream.Stream;
import org.jmolecules.ddd.types.Association;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.BeanUtils;
@ -283,6 +284,27 @@ public class KotlinPropertyAccessorFactoryTests { @@ -283,6 +284,27 @@ public class KotlinPropertyAccessorFactoryTests {
propertyAccessor.setProperty(createdBy, BeanUtils.instantiateClass(declaredConstructor, "baz"));
}
@MethodSource("factories")
@ParameterizedTest // GH-3131
void shouldApplyCopyForSinglePropertyClass(PersistentPropertyAccessorFactory factory) {
BasicPersistentEntity<Object, SamplePersistentProperty> entity = mappingContext
.getRequiredPersistentEntity(DataClassWithAssociation.class);
var foo = Association.forAggregate(new DataClassAggregate(new DataClassId("foo")));
var bar = Association.forAggregate(new DataClassAggregate(new DataClassId("bar")));
Object instance = createInstance(entity, parameter -> foo);
var propertyAccessor = factory.getPropertyAccessor(entity, instance);
var persistentProperty = entity.getRequiredPersistentProperty("assoc");
assertThat(propertyAccessor).isNotNull();
assertThat(propertyAccessor.getProperty(persistentProperty)).isEqualTo(foo);
propertyAccessor.setProperty(persistentProperty, bar);
assertThat(propertyAccessor.getProperty(persistentProperty)).isEqualTo(bar);
}
private Object createInstance(BasicPersistentEntity<?, SamplePersistentProperty> entity,
Function<Parameter<?, ?>, Object> parameterProvider) {
return instantiators.getInstantiatorFor(entity).createInstance(entity,

15
src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt

@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
*/
package org.springframework.data.mapping.model
import org.jmolecules.ddd.types.AggregateRoot
import org.jmolecules.ddd.types.Identifier
import org.springframework.data.annotation.Id
import java.time.LocalDateTime
@ -36,6 +38,19 @@ data class DataClassWithLazy( @@ -36,6 +38,19 @@ data class DataClassWithLazy(
val foo by lazy { 123 }
}
data class DataClassWithAssociation(
val assoc: org.jmolecules.ddd.types.Association<DataClassAggregate, DataClassId>
)
data class DataClassId(val id: String) : Identifier {
}
data class DataClassAggregate(val identifier: DataClassId) :
AggregateRoot<DataClassAggregate, DataClassId> {
override fun getId() = this.identifier
}
data class SingleSettableProperty constructor(val id: Double = Math.random()) {
val version: Int? = null
}

Loading…
Cancel
Save