Skip to content

Reading into existing instance uses creator property setup instead of accessor #5281

@odrotbohm

Description

@odrotbohm

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

When reading into an existing object, the JsonMapper uses the deserializer of the creator property instead of the parameter of the accessor.

package example.three;

import static org.assertj.core.api.Assertions.*;

import tools.jackson.databind.json.JsonMapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Stream;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;

class Jackson3Test {

  @Test
  void readsIntoCreator() throws Exception {

    var mapper = JsonMapper.builder()
        .build();

    mapper.readerForUpdating(new ArrayListHolder("A")).readValue("""
        {
          "values" : [ "A", "B" ]
        }
        """);
  }

  public static class ArrayListHolder {
    Collection<String> values;

    ArrayListHolder(String... values) {
      this.values = new ArrayList<>(Arrays.asList(values));
    }

    public void setValues(Collection<String> values) {
      this.values = values;
    }
  }
}

Stack trace:

tools.jackson.databind.DatabindException: Cannot cast [Ljava.lang.String; to java.util.Collection
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); byte offset: #UNKNOWN] (through reference chain: example.three.Jackson3Test$ArrayListHolder["values"])
	at tools.jackson.databind.DatabindException.wrapWithPath(DatabindException.java:111)
	at tools.jackson.databind.deser.bean.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1850)
	at tools.jackson.databind.deser.bean.BeanDeserializer.deserialize(BeanDeserializer.java:288)
	at tools.jackson.databind.deser.DeserializationContextExt.readRootValue(DeserializationContextExt.java:267)
	at tools.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1702)
	at tools.jackson.databind.ObjectReader.readValue(ObjectReader.java:1220)
	at example.three.Jackson3Test.readsIntoCreator(Jackson3Test.java:102)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.lang.ClassCastException: Cannot cast [Ljava.lang.String; to java.util.Collection
	at java.base/java.lang.Class.cast(Class.java:4067)
	at tools.jackson.databind.deser.impl.MethodProperty.set(MethodProperty.java:179)
	at tools.jackson.databind.deser.CreatorProperty.deserializeAndSet(CreatorProperty.java:219)
	at tools.jackson.databind.deser.bean.BeanDeserializer.deserialize(BeanDeserializer.java:286)
	... 7 more

Works on Jackson 2.

Version Information

3.0 RC8

Reproduction

No response

Expected behavior

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.xIssues to be only tackled for Jackson 3.x, not 2.xto-evaluateIssue that has been received but not yet evaluated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions