Skip to content

Commit 2c0ca6d

Browse files
authored
Fix #5238 @JsonIdentityInfo w/ Records (#5239)
1 parent 6c5f228 commit 2c0ca6d

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Not yet released
1010
(reported by @lbonco)
1111
#5237: Failing `@JsonMerge` with a custom Map with a `@JsonCreator` constructor
1212
(reported by @nlisker)
13+
#5238: Immutable classes with `@JsonIdentityInfo` can be deserialized; records cannot
14+
(fix by Joo-Hyuk K)
1315
#5242: Support "binary vectors": `@JsonFormat(shape = Shape.BINARY)` for
1416
`float[]`, `double[]`
1517
#5257: Deprecate `URL`-taking `readValue()` methods in `ObjectMapper`, `ObjectReader`

src/main/java/com/fasterxml/jackson/databind/deser/impl/PropertyValueBuffer.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
import com.fasterxml.jackson.core.JsonParser;
77
import com.fasterxml.jackson.databind.*;
8-
import com.fasterxml.jackson.databind.deser.SettableAnyProperty;
9-
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
8+
import com.fasterxml.jackson.databind.deser.*;
109
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
10+
import com.fasterxml.jackson.databind.util.ClassUtil;
1111
import com.fasterxml.jackson.databind.util.TokenBuffer;
1212

1313
/**
@@ -336,7 +336,12 @@ public Object handleIdValue(final DeserializationContext ctxt, Object bean) thro
336336
// also: may need to set a property value as well
337337
SettableBeanProperty idProp = _objectIdReader.idProperty;
338338
if (idProp != null) {
339-
return idProp.setAndReturn(bean, _idValue);
339+
// [databind#5328] Records/Creators do not have setters, skip
340+
if (idProp instanceof CreatorProperty) {
341+
return bean;
342+
} else {
343+
return idProp.setAndReturn(bean, _idValue);
344+
}
340345
}
341346
} else {
342347
// 07-Jun-2016, tatu: Trying to improve error messaging here...
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import java.util.List;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
import com.fasterxml.jackson.annotation.*;
8+
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
// [databind#5238] immutable classes with @JsonIdentityInfo can be deserialized; records cannot
14+
public class JsonIdentityOnRecord5238Test
15+
extends DatabindTestUtil
16+
{
17+
// Record-based data
18+
record ExampleRecord(List<ThingRecord> allThings, ThingRecord selected) { }
19+
20+
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
21+
record ThingRecord(int id, String name) { }
22+
23+
// POJO-based data
24+
static class ExamplePojo {
25+
public List<ThingPojo> allThings;
26+
public ThingPojo selected;
27+
28+
@JsonCreator
29+
public ExamplePojo(
30+
@JsonProperty("allThings") List<ThingPojo> allThings,
31+
@JsonProperty("selected") ThingPojo selected) {
32+
this.allThings = allThings;
33+
this.selected = selected;
34+
}
35+
}
36+
37+
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
38+
static class ThingPojo {
39+
public final int id;
40+
public final String name;
41+
42+
@JsonCreator
43+
public ThingPojo(@JsonProperty("prefixId") int id, @JsonProperty("name") String name) {
44+
this.id = id;
45+
this.name = name;
46+
}
47+
}
48+
49+
private final ObjectMapper MAPPER = newJsonMapper();
50+
51+
@Test
52+
void testIdentityWithPojo() throws Exception {
53+
ThingPojo t1 = new ThingPojo(1, "a");
54+
ThingPojo t2 = new ThingPojo(2, "b");
55+
ExamplePojo input = new ExamplePojo(List.of(t1, t2), t2);
56+
57+
String json = MAPPER.writeValueAsString(input);
58+
59+
// Then : Check deserialization result, values
60+
ExamplePojo result = MAPPER.readValue(json, ExamplePojo.class);
61+
assertEquals(input.allThings.size(), result.allThings.size());
62+
assertEquals(input.selected.id, result.selected.id);
63+
assertEquals(input.selected.name, result.selected.name);
64+
}
65+
66+
@Test
67+
void testIdentityWithRecord() throws Exception {
68+
// Given
69+
ThingRecord t1 = new ThingRecord(1, "a");
70+
ThingRecord t2 = new ThingRecord(2, "b");
71+
ExampleRecord input = new ExampleRecord(List.of(t1, t2), t2);
72+
73+
// When
74+
String json = MAPPER.writeValueAsString(input);
75+
ExampleRecord result = MAPPER.readValue(json, ExampleRecord.class);
76+
77+
// Then
78+
assertEquals(input.allThings.size(), result.allThings.size());
79+
assertEquals(input.selected.id, result.selected.id);
80+
assertEquals(input.selected.name, result.selected.name);
81+
}
82+
83+
}

0 commit comments

Comments
 (0)