Adapt to renamed properties by using MappedProperties in association deserialization.

Revert the changes that employed manual annotation lookup as that would cause invalid associations of fields and accessor methods for properties shadow renamed. Instead, we now use MappedProperties that already contains a mapping between the Jackson field names and Sprign Data property names.

Fixes: #2165
This commit is contained in:
Oliver Drotbohm
2023-02-21 13:24:39 +01:00
parent 5335fe61e9
commit b65e0c9118
3 changed files with 8 additions and 23 deletions

View File

@@ -151,6 +151,10 @@ class MappedProperties {
return new MappedProperties(entity, description);
}
public static MappedProperties forDescription(PersistentEntity<?, ?> entity, BeanDescription description) {
return new MappedProperties(entity, description);
}
public static MappedProperties none() {
return new MappedProperties(Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet(),
Collections.emptySet(), false);

View File

@@ -24,7 +24,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import org.slf4j.Logger;
@@ -83,8 +82,6 @@ import com.fasterxml.jackson.databind.deser.std.CollectionDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -445,21 +442,12 @@ public class PersistentEntityJackson2Module extends SimpleModule {
entities.getPersistentEntity(beanDesc.getBeanClass()).ifPresent(entity -> {
MappedProperties mapped = MappedProperties.forDescription(entity, beanDesc);
while (properties.hasNext()) {
SettableBeanProperty property = properties.next();
// To find the PersistentProperty name in case there is a @JsonProperty annotation
// on the field. Both BeanPropertyDefinition#getName() and BeanPropertyDefinition#getInternalName()
// don't return the actual name of the field, so we look up the AnnotatedField itself to retrieve
// the real name from, so it can be used for PersistentProperty lookup
String persistentPropertyName = beanDesc.findProperties().stream()
.filter(propertyDefinition -> property.getName().equals(propertyDefinition.getName()))
.map(BeanPropertyDefinition::getField).filter(Objects::nonNull).map(AnnotatedField::getName).findFirst()
// Fall back to the JSON name in case we can't find a BeanPropertyDefinition,
// so things can be mapped by convention in case they are immutable objects and are
// using constructor injection
.orElse(property.getName());
PersistentProperty<?> persistentProperty = entity.getPersistentProperty(persistentPropertyName);
PersistentProperty<?> persistentProperty = mapped.getPersistentProperty(property.getName());
if (persistentProperty == null) {
continue;

View File

@@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
@@ -190,10 +189,9 @@ class PersistentEntityJackson2ModuleUnitTests {
PetOwner petOwner = mapper.readValue("{\"package\":\"/packages/1\"}", PetOwner.class);
assertThat(petOwner).isNotNull();
assertThat(petOwner.getPackage()).isNotNull();
assertThat(petOwner._package).isNotNull();
}
@Test // DATAREST-1321
void allowsNumericIdsForLookupTypes() throws Exception {
@@ -298,12 +296,7 @@ class PersistentEntityJackson2ModuleUnitTests {
Pet pet;
Home home;
@Getter(value = AccessLevel.NONE)
@JsonProperty("package") Package _package;
public Package getPackage() {
return _package;
}
}
static class Package {}