DATAREST-1393 - Introduce workaround for Jackson property customization bug.

Deserializer customizations for related resources (deserializing an instance from a URI) are not applied to the creator properties Jackson uses to create an entity instance in the first place (see [0] for details). We work around this now by tweaking the property instances used for that in their origin ValueInstantiator via reflection until the bug gets fixed.

[0] https://github.com/FasterXML/jackson-databind/issues/2367
This commit is contained in:
Oliver Drotbohm
2019-06-25 15:59:01 +02:00
parent 6ed2ae4566
commit d7b66777da
2 changed files with 102 additions and 5 deletions

View File

@@ -51,7 +51,6 @@ import org.springframework.data.rest.webmvc.mapping.Associations;
import org.springframework.data.rest.webmvc.support.ExcerptProjector;
import org.springframework.hateoas.UriTemplate;
import org.springframework.hateoas.server.EntityLinks;
import org.springframework.hateoas.server.RepresentationModelProcessor;
import org.springframework.hateoas.server.mvc.RepresentationModelProcessorInvoker;
import org.springframework.plugin.core.PluginRegistry;
@@ -89,11 +88,11 @@ public class PersistentEntityJackson2ModuleUnitTests {
mappingContext.getPersistentEntity(Sample.class);
mappingContext.getPersistentEntity(SampleWithAdditionalGetters.class);
mappingContext.getPersistentEntity(PersistentEntityJackson2ModuleUnitTests.PetOwner.class);
mappingContext.getPersistentEntity(Immutable.class);
this.persistentEntities = new PersistentEntities(Arrays.asList(mappingContext));
RepresentationModelProcessorInvoker invoker = new RepresentationModelProcessorInvoker(
Collections.<RepresentationModelProcessor<?>> emptyList());
RepresentationModelProcessorInvoker invoker = new RepresentationModelProcessorInvoker(Collections.emptyList());
NestedEntitySerializer nestedEntitySerializer = new NestedEntitySerializer(persistentEntities,
new EmbeddedResourcesAssembler(persistentEntities, associations, mock(ExcerptProjector.class)), invoker);
@@ -183,6 +182,21 @@ public class PersistentEntityJackson2ModuleUnitTests {
.isEqualTo(41);
}
@Test // DATAREST-1393
public void customizesDeserializerForCreatorProperties() throws Exception {
PersistentProperty<?> property = persistentEntities //
.getRequiredPersistentEntity(Immutable.class) //
.getRequiredPersistentProperty("home");
when(associations.isLinkableAssociation(property)).thenReturn(true);
mapper.readValue("{ \"home\" : \"homes:4711\"}", Immutable.class);
verify(converter).convert(URI.create("homes:4711"), TypeDescriptor.valueOf(URI.class),
TypeDescriptor.valueOf(Home.class));
}
/**
* @author Oliver Gierke
*/
@@ -234,4 +248,13 @@ public class PersistentEntityJackson2ModuleUnitTests {
return 5;
}
}
static class Immutable {
private final @SuppressWarnings("unused") Home home;
public Immutable(@JsonProperty("home") Home home) {
this.home = home;
}
}
}