From cd3f9cb462b6d979704487f72d53d9e07f3b1154 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Tue, 21 Feb 2023 13:24:39 +0100 Subject: [PATCH] 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 Spring Data property names. Fixes: #2165 $ Conflicts: $ spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java $ spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java --- .../rest/webmvc/json/MappedProperties.java | 4 ++ .../json/PersistentEntityJackson2Module.java | 4 +- ...rsistentEntityJackson2ModuleUnitTests.java | 38 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/MappedProperties.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/MappedProperties.java index bb14a0853..0517577c1 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/MappedProperties.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/MappedProperties.java @@ -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); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java index 1722fee08..42ab18c7c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java @@ -441,10 +441,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(); - PersistentProperty persistentProperty = entity.getPersistentProperty(property.getName()); + PersistentProperty persistentProperty = mapped.getPersistentProperty(property.getName()); if (persistentProperty == null) { continue; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java index 3bcfe2fab..238d670b4 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java @@ -157,6 +157,40 @@ class PersistentEntityJackson2ModuleUnitTests { assertThat(petOwner.getPet()).isNotNull(); } + @Test + void allowsUrlsForLinkableAssociation() throws Exception { + + when(converter.convert(UriTemplate.of("/homes/1").expand(), TypeDescriptor.valueOf(URI.class), + TypeDescriptor.valueOf(Home.class))).thenReturn(new Home()); + + PersistentProperty property = persistentEntities.getRequiredPersistentEntity(PetOwner.class) + .getRequiredPersistentProperty("home"); + + when(associations.isLinkableAssociation(property)).thenReturn(true); + + PetOwner petOwner = mapper.readValue("{\"home\": \"/homes/1\" }", PetOwner.class); + + assertThat(petOwner).isNotNull(); + assertThat(petOwner.getHome()).isInstanceOf(Home.class); + } + + @Test + void allowsUrlsForRenamedLinkableAssociation() throws IOException { + + when(converter.convert(UriTemplate.of("/packages/1").expand(), TypeDescriptor.valueOf(URI.class), + TypeDescriptor.valueOf(Package.class))).thenReturn(new Package()); + + PersistentProperty property = persistentEntities.getRequiredPersistentEntity(PetOwner.class) + .getRequiredPersistentProperty("_package"); + + when(associations.isLinkableAssociation(property)).thenReturn(true); + + PetOwner petOwner = mapper.readValue("{\"package\":\"/packages/1\"}", PetOwner.class); + + assertThat(petOwner).isNotNull(); + assertThat(petOwner._package).isNotNull(); + } + @Test // DATAREST-1321 void allowsNumericIdsForLookupTypes() throws Exception { @@ -260,8 +294,12 @@ class PersistentEntityJackson2ModuleUnitTests { Pet pet; Home home; + + @JsonProperty("package") Package _package; } + static class Package {} + @JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.MINIMAL_CLASS) static class Pet {}