From ba28fe38a1c67fffd846adad6d4365368882fbd8 Mon Sep 17 00:00:00 2001 From: "Kim, Joo Hyuk" Date: Thu, 4 Jul 2024 12:14:05 +0900 Subject: [PATCH] fix #4610 (#4611) --- release-notes/VERSION-2.x | 3 + .../databind/deser/BeanDeserializer.java | 5 +- .../objectid/ObjectIdSubTypes4610Test.java | 76 +++++++++++++++++++ .../failing/ObjectIdSubTypes4607Test.java | 38 ---------- 4 files changed, 83 insertions(+), 39 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/objectid/ObjectIdSubTypes4610Test.java delete mode 100644 src/test/java/com/fasterxml/jackson/failing/ObjectIdSubTypes4607Test.java diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 997a989c5f..86a5477772 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -18,6 +18,9 @@ Project: jackson-databind (reported by @dmelisso) #4595: No way to explicitly disable wrapping in custom annotation processor (reported by @SimonCockx) +#4610: `DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS` does not work when + used with Polymorphic type handling + (fix by Joo-Hyuk K) 2.17.1 (04-May-2024) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java index 25ae119c6c..010d6a98df 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java @@ -372,7 +372,10 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t // [databind#3838]: since 2.16 Uniform handling of missing objectId // only for the specific "empty JSON Object" case if (_objectIdReader != null && p.hasTokenId(JsonTokenId.ID_END_OBJECT)) { - ctxt.reportUnresolvedObjectId(_objectIdReader, bean); + // [databind#4610]: check if we are to skip failure + if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)) { + ctxt.reportUnresolvedObjectId(_objectIdReader, bean); + } } if (_injectables != null) { injectValues(ctxt, bean); diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/ObjectIdSubTypes4610Test.java b/src/test/java/com/fasterxml/jackson/databind/objectid/ObjectIdSubTypes4610Test.java new file mode 100644 index 0000000000..7fa3c87260 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/ObjectIdSubTypes4610Test.java @@ -0,0 +1,76 @@ +package com.fasterxml.jackson.databind.objectid; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.annotation.*; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; + +import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ObjectIdSubTypes4610Test extends DatabindTestUtil +{ + // Unused @JsonIdentityInfo + @JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class) + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = EnumTypeDefinition.class, name = "enum"), + @JsonSubTypes.Type(value = NumberTypeDefinition.class, name = "number") + }) + interface TypeDefinition { + } + + static class EnumTypeDefinition implements TypeDefinition { + public List values; + } + + static class NumberTypeDefinition implements TypeDefinition { + } + + private final ObjectMapper MAPPER = newJsonMapper(); + + @Test + public void shouldHandleTypeDefinitionJson() throws Exception { + String input = "{\"@type\": \"number\"}"; + + TypeDefinition model = MAPPER.readerFor(TypeDefinition.class) + .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(input); + + Assertions.assertInstanceOf(NumberTypeDefinition.class, model); + } + + @Test + public void testRoundTrip() throws Exception { + // Ser + String JSON = MAPPER.writeValueAsString(new NumberTypeDefinition()); + assertTrue(JSON.contains("@id")); + + // Deser + TypeDefinition model = MAPPER.readerFor(TypeDefinition.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(JSON); + Assertions.assertInstanceOf(NumberTypeDefinition.class, model); + } + + @Test + public void shouldHandleTypeDefinitionJsonFail() throws Exception { + String JSON = "{\"@type\": \"number\"}"; + + try { + /*TypeDefinition model =*/ MAPPER.readerFor(TypeDefinition.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(JSON); + fail("Should not pass"); + } catch (Exception e) { + assertTrue(e.getMessage().startsWith("No Object Id found for an instance of")); + } + } +} + diff --git a/src/test/java/com/fasterxml/jackson/failing/ObjectIdSubTypes4607Test.java b/src/test/java/com/fasterxml/jackson/failing/ObjectIdSubTypes4607Test.java deleted file mode 100644 index dd380e76cb..0000000000 --- a/src/test/java/com/fasterxml/jackson/failing/ObjectIdSubTypes4607Test.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.fasterxml.jackson.failing; - -import java.util.List; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.annotation.*; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; - -public class ObjectIdSubTypes4607Test extends DatabindTestUtil -{ - @JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class) - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) - @JsonSubTypes({ - @JsonSubTypes.Type(value = EnumTypeDefinition.class, name = "enum"), - @JsonSubTypes.Type(value = NumberTypeDefinition.class, name = "number") - }) - interface TypeDefinition { - } - - static class EnumTypeDefinition implements TypeDefinition { - public List values; - } - - static class NumberTypeDefinition implements TypeDefinition { - } - - @Test - public void shouldHandleTypeDefinitionJson() throws Exception { - final ObjectMapper mapper = newJsonMapper(); - TypeDefinition model = mapper.readValue("{ \"@type\": \"number\" }", TypeDefinition.class); - Assertions.assertInstanceOf(NumberTypeDefinition.class, model); - } -} -