Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing records deserialization issues with read-access when json renamed to same property name #5072

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1812,7 +1812,8 @@ protected boolean _replaceCreatorProperty(List<POJOPropertyBuilder> creatorPrope
for (int i = 0, len = creatorProperties.size(); i < len; ++i) {
POJOPropertyBuilder cprop = creatorProperties.get(i);
if (cprop != null) {
if (cprop.getConstructorParameter() == ctorParam) {
AnnotatedParameter cpropParam = cprop.getConstructorParameter();
if (cpropParam == ctorParam && cpropParam != null) {
creatorProperties.set(i, prop);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.databind.records;

import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -64,9 +65,10 @@ public void testSerializeJsonIgnoreAndJsonPropertyRecord() throws Exception {
}

@Test
@JacksonTestFailureExpected
public void testDeserializeJsonIgnoreAndJsonPropertyRecord() throws Exception {
RecordWithIgnoreJsonProperty value = MAPPER.readValue("{\"id\":123,\"name\":\"Bob\"}", RecordWithIgnoreJsonProperty.class);
assertEquals(new RecordWithIgnoreJsonProperty(123, "Bob"), value);
assertEquals(new RecordWithIgnoreJsonProperty(123, null), value); // should be null, actual "bob" [see databind-4628]
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

public class RecordWithReadOnlyTest extends DatabindTestUtil
{
Expand Down Expand Up @@ -53,6 +55,27 @@ public RecordWithReadOnlyAllAndNoArgConstructor() {
}
}


static class ReadOnly5049Pojo
{
protected String a, b;

ReadOnly5049Pojo(
@JsonProperty(value = "a", access = JsonProperty.Access.READ_ONLY) String a,
@JsonProperty(value = "b", access = JsonProperty.Access.READ_ONLY) String b) {
this.a = a;
this.b = b;
}

public String getA() { return a; }
public String getB() { return b; }
}

record ReadOnly5049Record(
@JsonProperty(value = "a", access = JsonProperty.Access.READ_ONLY) String a,
@JsonProperty(value = "b", access = JsonProperty.Access.READ_ONLY) String b) {
}

private final ObjectMapper MAPPER = newJsonMapper();

/*
Expand Down Expand Up @@ -85,19 +108,33 @@ public void testSerializeReadOnlyNamedProperty() throws Exception {
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
}

/**
* Currently documents a bug where a property was NOT ignored during deserialization
* if given an explicit name.
* Also reproducible in 2.14.x.
*/

@Test
public void testDeserializeReadOnlyNamedProperty() throws Exception {
RecordWithReadOnlyNamedProperty value = MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"),
RecordWithReadOnlyNamedProperty.class);

// BUG: should be `null` instead of "Bob"
// 01-Apr-2025, tatu: Should be in "tofix", then?
assertEquals(new RecordWithReadOnlyNamedProperty(123, "Bob"), value);
assertEquals(new RecordWithReadOnlyNamedProperty(123, null), value);
}

@Test
void testRoundtripPOJO() throws Exception
{
String json = MAPPER.writeValueAsString(new ReadOnly5049Pojo("hello", "world"));
ReadOnly5049Pojo pojo = MAPPER.readerFor(ReadOnly5049Pojo.class).readValue(json);
assertNotNull(pojo);
assertNull(pojo.a);
assertNull(pojo.b);
}

@Test
void testRoundtripRecord() throws Exception
{
String json = MAPPER.writeValueAsString(new ReadOnly5049Record("hello", "world"));
ReadOnly5049Record record = MAPPER.readValue(json, ReadOnly5049Record.class);
assertNotNull(record);
assertNull(record.a());
assertNull(record.b());
}

/*
Expand Down

This file was deleted.