Skip to content

Commit 9f80462

Browse files
authored
Fix #3938: do not skip Method-based setters on Records (#3939)
1 parent 3291911 commit 9f80462

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

release-notes/VERSION-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Project: jackson-databind
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.15.2 (not yet released)
8+
9+
#3938: Record setter not included from interface (2.15 regression)
10+
711
2.15.1 (16-May-2023)
812

913
#3882: Error in creating nested `ArrayNode`s with `JsonNode.withArray()`

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,9 @@ protected Object _deserializeUsingPropertyBased(final JsonParser p, final Deseri
470470
// weren't removed (to help in creating constructor-backed PropertyCreator)
471471
// so they ended up in _beanProperties, unlike POJO (whose ignored
472472
// props are removed)
473-
if ((prop != null) && !_beanType.isRecordType()) {
473+
if ((prop != null) &&
474+
// [databind#3938]: except if it's MethodProperty
475+
(!_beanType.isRecordType() || (prop instanceof MethodProperty))) {
474476
try {
475477
buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop));
476478
} catch (UnresolvedForwardReference reference) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.*;
5+
6+
public class RecordFailingSetter3938Test extends BaseMapTest
7+
{
8+
private final static String ERROR_3938_PREFIX = "Non-null 'options' not allowed for ";
9+
10+
// [databind#3938]
11+
interface NoOptionsCommand {
12+
@JsonProperty("options")
13+
default void setOptions(JsonNode value) {
14+
if (value.isNull()) {
15+
return;
16+
}
17+
throw new IllegalArgumentException(ERROR_3938_PREFIX+getClass().getName());
18+
}
19+
}
20+
21+
public record Command3938(int id, String filter) implements NoOptionsCommand { }
22+
23+
private final ObjectMapper MAPPER = newJsonMapper();
24+
25+
// [databind#3938]: Should detect and use setters too
26+
public void testFailingSetter3939() throws Exception
27+
{
28+
final ObjectReader R = MAPPER.readerFor(Command3938.class);
29+
30+
// First, missing value and `null` are fine, as long as we have all fields
31+
assertNotNull(R.readValue(a2q("{'id':1, 'filter':'abc'}")));
32+
assertNotNull(R.readValue(a2q("{'id':2, 'filter':'abc', 'options':null}")));
33+
34+
// But then failure for non-empty Array (f.ex)
35+
try {
36+
R.readValue(a2q("{'id':2,'options':[123]}}"));
37+
fail("Should not pass");
38+
} catch (DatabindException e) {
39+
verifyException(e, ERROR_3938_PREFIX);
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)