Skip to content

Commit

Permalink
Fix #3938: do not skip Method-based setters on Records (#3939)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder authored May 18, 2023
1 parent 3291911 commit 9f80462
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
4 changes: 4 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------

2.15.2 (not yet released)

#3938: Record setter not included from interface (2.15 regression)

2.15.1 (16-May-2023)

#3882: Error in creating nested `ArrayNode`s with `JsonNode.withArray()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,9 @@ protected Object _deserializeUsingPropertyBased(final JsonParser p, final Deseri
// weren't removed (to help in creating constructor-backed PropertyCreator)
// so they ended up in _beanProperties, unlike POJO (whose ignored
// props are removed)
if ((prop != null) && !_beanType.isRecordType()) {
if ((prop != null) &&
// [databind#3938]: except if it's MethodProperty
(!_beanType.isRecordType() || (prop instanceof MethodProperty))) {
try {
buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop));
} catch (UnresolvedForwardReference reference) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.fasterxml.jackson.databind.records;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.*;

public class RecordFailingSetter3938Test extends BaseMapTest
{
private final static String ERROR_3938_PREFIX = "Non-null 'options' not allowed for ";

// [databind#3938]
interface NoOptionsCommand {
@JsonProperty("options")
default void setOptions(JsonNode value) {
if (value.isNull()) {
return;
}
throw new IllegalArgumentException(ERROR_3938_PREFIX+getClass().getName());
}
}

public record Command3938(int id, String filter) implements NoOptionsCommand { }

private final ObjectMapper MAPPER = newJsonMapper();

// [databind#3938]: Should detect and use setters too
public void testFailingSetter3939() throws Exception
{
final ObjectReader R = MAPPER.readerFor(Command3938.class);

// First, missing value and `null` are fine, as long as we have all fields
assertNotNull(R.readValue(a2q("{'id':1, 'filter':'abc'}")));
assertNotNull(R.readValue(a2q("{'id':2, 'filter':'abc', 'options':null}")));

// But then failure for non-empty Array (f.ex)
try {
R.readValue(a2q("{'id':2,'options':[123]}}"));
fail("Should not pass");
} catch (DatabindException e) {
verifyException(e, ERROR_3938_PREFIX);
}
}
}

0 comments on commit 9f80462

Please sign in to comment.