DATACMNS-1768 - Reuse bean state in InstantiationAwarePropertyAccessor when setting multiple properties.

We now reuse the new bean in InstantiationAwarePropertyAccessor when setting properties. Previously, we used the initial bean state as the bean was held by a delegate PersistentPropertyAccessor which caused only the last set property to be visible.
This commit is contained in:
Mark Paluch
2020-07-14 09:38:06 +02:00
parent f6630a5dd5
commit ebcea509b8
4 changed files with 69 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2020 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.
@@ -26,12 +26,15 @@ import org.springframework.data.mapping.context.SamplePersistentProperty;
import org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor;
/**
* Unit tests for {@link InstantiationAwarePropertyAccessor}.
*
* @author Oliver Drotbohm
* @author Mark Paluch
*/
public class InstantiationAwarePersistentPropertyAccessorUnitTests {
@Test
public void testname() {
@Test // DATACMNS-1639
public void shouldCreateNewInstance() {
EntityInstantiators instantiators = new EntityInstantiators();
SampleMappingContext context = new SampleMappingContext();
@@ -48,6 +51,25 @@ public class InstantiationAwarePersistentPropertyAccessorUnitTests {
assertThat(wrapper.getBean()).isEqualTo(new Sample("Oliver August", "Matthews", 42));
}
@Test // DATACMNS-1768
public void shouldSetMultipleProperties() {
EntityInstantiators instantiators = new EntityInstantiators();
SampleMappingContext context = new SampleMappingContext();
PersistentEntity<Object, SamplePersistentProperty> entity = context.getRequiredPersistentEntity(Sample.class);
Sample bean = new Sample("Dave", "Matthews", 42);
PersistentPropertyAccessor<Sample> wrapper = new InstantiationAwarePropertyAccessor<>(bean,
entity::getPropertyAccessor, instantiators);
wrapper.setProperty(entity.getRequiredPersistentProperty("firstname"), "Oliver August");
wrapper.setProperty(entity.getRequiredPersistentProperty("lastname"), "Heisenberg");
assertThat(wrapper.getBean()).isEqualTo(new Sample("Oliver August", "Heisenberg", 42));
}
@Value
static class Sample {

View File

@@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@@ -186,7 +187,8 @@ class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
.hasMessageContaining("Required property foo not found");
}
@Test // DATACMNS-809
@Test // DATACMNS-809, DATACMNS-1768
@SuppressWarnings("rawtypes")
void returnsGeneratedPropertyAccessorForPropertyAccessor() {
SampleMappingContext context = new SampleMappingContext();
@@ -196,11 +198,12 @@ class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value);
assertThat(accessor).isNotInstanceOf(BeanWrapper.class);
assertThat(accessor).isInstanceOfSatisfying(InstantiationAwarePropertyAccessor.class, it -> {
PersistentPropertyAccessor delegate = (PersistentPropertyAccessor) ReflectionTestUtils.getField(it, "delegate");
Function<Object, PersistentPropertyAccessor<Object>> delegateFunction = (Function<Object, PersistentPropertyAccessor<Object>>) ReflectionTestUtils
.getField(it, "delegateFunction");
PersistentPropertyAccessor<Object> delegate = delegateFunction.apply(value);
assertThat(delegate.getClass().getName()).contains("_Accessor_");
assertThat(delegate.getBean()).isEqualTo(value);
});