Skip to content

Commit 5ddede1

Browse files
committed
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
1 parent a976759 commit 5ddede1

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

Diff for: src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.core.ResolvableType;
3939
import org.springframework.data.mapping.PersistentEntity;
4040
import org.springframework.data.mapping.PersistentProperty;
41+
import org.springframework.data.mapping.SimpleAssociationHandler;
4142
import org.springframework.data.mapping.SimplePropertyHandler;
4243
import org.springframework.data.util.KotlinReflectionUtils;
4344
import org.springframework.util.Assert;
@@ -158,8 +159,9 @@ boolean shouldUsePublicCopyMethod(PersistentEntity<?, ?> entity) {
158159

159160
List<PersistentProperty<?>> persistentProperties = new ArrayList<>();
160161
entity.doWithProperties((SimplePropertyHandler) persistentProperties::add);
162+
entity.doWithAssociations((SimpleAssociationHandler) it -> persistentProperties.add(it.getInverse()));
161163

162-
if (persistentProperties.size() > 1) {
164+
if (persistentProperties.size() != 1) {
163165
return false;
164166
}
165167

Diff for: src/test/java/org/springframework/data/mapping/model/KotlinPropertyAccessorFactoryTests.java

+22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.function.Function;
2626
import java.util.stream.Stream;
2727

28+
import org.jmolecules.ddd.types.Association;
2829
import org.junit.jupiter.params.ParameterizedTest;
2930
import org.junit.jupiter.params.provider.MethodSource;
3031
import org.springframework.beans.BeanUtils;
@@ -283,6 +284,27 @@ void shouldUnwrapValueTypeIfNecessary(PersistentPropertyAccessorFactory factory)
283284
propertyAccessor.setProperty(createdBy, BeanUtils.instantiateClass(declaredConstructor, "baz"));
284285
}
285286

287+
@MethodSource("factories")
288+
@ParameterizedTest // GH-3131
289+
void shouldApplyCopyForSinglePropertyClass(PersistentPropertyAccessorFactory factory) {
290+
291+
BasicPersistentEntity<Object, SamplePersistentProperty> entity = mappingContext
292+
.getRequiredPersistentEntity(DataClassWithAssociation.class);
293+
294+
var foo = Association.forAggregate(new DataClassAggregate(new DataClassId("foo")));
295+
var bar = Association.forAggregate(new DataClassAggregate(new DataClassId("bar")));
296+
Object instance = createInstance(entity, parameter -> foo);
297+
298+
var propertyAccessor = factory.getPropertyAccessor(entity, instance);
299+
var persistentProperty = entity.getRequiredPersistentProperty("assoc");
300+
301+
assertThat(propertyAccessor).isNotNull();
302+
assertThat(propertyAccessor.getProperty(persistentProperty)).isEqualTo(foo);
303+
304+
propertyAccessor.setProperty(persistentProperty, bar);
305+
assertThat(propertyAccessor.getProperty(persistentProperty)).isEqualTo(bar);
306+
}
307+
286308
private Object createInstance(BasicPersistentEntity<?, SamplePersistentProperty> entity,
287309
Function<Parameter<?, ?>, Object> parameterProvider) {
288310
return instantiators.getInstantiatorFor(entity).createInstance(entity,

Diff for: src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt

+15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.mapping.model
1717

18+
import org.jmolecules.ddd.types.AggregateRoot
19+
import org.jmolecules.ddd.types.Identifier
1820
import org.springframework.data.annotation.Id
1921
import java.time.LocalDateTime
2022

@@ -36,6 +38,19 @@ data class DataClassWithLazy(
3638
val foo by lazy { 123 }
3739
}
3840

41+
data class DataClassWithAssociation(
42+
val assoc: org.jmolecules.ddd.types.Association<DataClassAggregate, DataClassId>
43+
)
44+
45+
data class DataClassId(val id: String) : Identifier {
46+
47+
}
48+
49+
data class DataClassAggregate(val identifier: DataClassId) :
50+
AggregateRoot<DataClassAggregate, DataClassId> {
51+
override fun getId() = this.identifier
52+
}
53+
3954
data class SingleSettableProperty constructor(val id: Double = Math.random()) {
4055
val version: Int? = null
4156
}

0 commit comments

Comments
 (0)