Skip to content

InvalidDefinitionException "No fallback setter/field defined for creator property" when deserializing JSON with duplicated property to single-property Record #4690

@sseelmann

Description

@sseelmann

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

Deserialzing a JSON with a duplicated property fails for a Java Record with a single property.

Version Information

2.17.2

Reproduction

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.databind.ObjectMapper;

class JacksonDeserializationTest {

	record MyRecord(String first) {
	}

	@Test
	void test() throws Exception {
		ObjectMapper mapper = new ObjectMapper();

		String json = """
				{
					"first": "test@example.com",
					"first": "test@example.com"
				}
				""";
		var value = mapper.readValue(json, MyRecord.class);
		System.out.println(value);
	}

}

Produces the following error:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No fallback setter/field defined for creator property 'first' (through reference chain: JacksonDeserializationTest$MyRecord["first"])
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.deser.CreatorProperty._reportMissingSetter(CreatorProperty.java:354)
	at com.fasterxml.jackson.databind.deser.CreatorProperty._verifySetter(CreatorProperty.java:341)
	at com.fasterxml.jackson.databind.deser.CreatorProperty.deserializeAndSet(CreatorProperty.java:270)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:273)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:470)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816)
	at JacksonDeserializationTest.test(JacksonDeserializationTest.java:20)
	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)


Expected behavior

Deserialization works, or a proper exception describing the problem (e.g. "duplicate property") is thrown.

Additional context

Workaround: Add a 2nd dummy property to the Java Record

Ofc the duplicate property in the JSON is not the default. It was detected during a penetration test when testing for parameter pollution vulnerabilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.1RecordIssue related to JDK17 java.lang.Record supporthas-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions