-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Java Record @JsonAnySetter
value is null after deserialization
#3439
Comments
Currently |
Thans for the hint @oujesky, I've managed to make it work:
|
I think this is basically duplicate of #562. |
Unfortunately it returns entries in reverse order :( |
So far, I've used the workaround with |
@kleino JsonAnySetter documents two ways:
You've been using #1, which is no longer usable because #3737 ignores Record fields for deserialization (so Jackson cannot "see" the You can still use #2:
|
Hmmh. Ideally we'd support |
Is there any intent to tackle this issue? It's blocking us from using records in many places, unfortunately. |
@lordvlad If someone was working on this, they'd likely add a note. So I doubt anyone is working on it. I do not have bandwidth myself, but perhaps @JooHyukKim might have? |
Note: #562 is the main issue wrt inability to use |
Just came across this issue, because I ran into it as well, but I wanted to share my workaround, which is similar to the one provided but uses a compact constructor to avoid the need for a "full constuctor" annotated with JsonCreator that replicates the entire arglist. This doesn't remove the fact that we're adding a mutable map to the record instance, which might be undesirable in some cases. record Person(String name, Map<String, Object> attributes) {
/**
* Creates a new instance. If {@code attributes} is null, a new <em>mutable</em> map is created
* and used instead.
*
* @param name the name
* @param attributes the attributes map, or null
*/
Person {
attributes = attributes == null
? new HashMap<>()
: attributes;
}
@JsonAnySetter
public void addAttribute(final String key, final Object value) {
attributes.put(key, value);
}
} |
@cowtowncoder I think this can be closed? |
Yes, will mark as fixed as of 2.18.0; close. |
Added a new test (similar to one for #562 but still); passes, closing as implemented |
Describe the bug
When deserializing a Java Record with
@JsonAnySetter
annotated field the field is left as null and the unmapped values are ignored. Given the nature of Java records, there is no other way to get the unmapped fields values (like in case of annotating a setter method).Version information
2.13.2.2
To Reproduce
Running this test the result will be:
Expected behavior
The
@JsonAnySetter
annotated field should contain a Map instance with all unmapped fields and their values.Additional context
The problem happens in
com.fasterxml.jackson.databind.deser.SettableAnyProperty
class in methodset(...)
. The value of the@JsonAnySetter
annotated field is null and therefore setting the property value is skipped.The suggested solution would be for Java Record to provide a new empty Map instance for the annotated field to gather the unmapped properties and this would then be provided to Record's constructor when the deserialization is concluded. Given the immutable nature of Java Records, this should ideally be some kind of immutable Map implementation (i.e.
Map.copyOf(...)
?)There might be a workaround (which however won't be probably feasible in all cases) by supplying an additional
@JsonCreator
constructor or factory method, where the@JsonAnySetter
field is initialized to an empty map and then to ensure the immutability, the getter for this map needs to be overridden and the value returned wrapped as immutable.The text was updated successfully, but these errors were encountered: