Getter that returns an abstract collection breaks a delegating `@JsonCreator`
See original GitHub issueUsing version 2.9.2 or 2.9.8 (and probably many other versions), the following test throws:
JsonMappingException: Cannot find a deserializer for non-concrete Collection type [collection type; class java.util.AbstractSet, contains [simple type, class java.lang.Integer]]
@Test
public void testDeserializeValSet() throws IOException {
new ObjectMapper().readValue("[1,2,3]", ValSet.class);
}
static class ValSet {
@JsonValue
private final AbstractSet<Integer> vals;
@JsonCreator(mode = Mode.DELEGATING)
ValSet(Collection<Integer> vals) {
this.vals = new HashSet<>(vals);
}
public AbstractSet<Integer> getVals() {
return vals;
}
}
This is a spurious error since the @JsonCreator
constructor only requires Collection<Integer>
, not AbstractSet<Integer>
.
Some workarounds:
- Delete
getVals()
. - Make
getVals()
non-public. - Move
@JsonValue
togetVals()
. - Add
@JsonIgnore
togetVals()
. - Add
@JsonAutoDetect(getterVisibility = Visibility.NONE)
toValSet
.
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (5 by maintainers)
Top Results From Across the Web
How to deserialize a class with overloaded constructors using ...
You can have as many constructors as you want in your type, but only one of them should have a @JsonCreator annotation on...
Read more >com.fasterxml.jackson.databind.deser ...
JsonCreator ; import com.fasterxml.jackson.annotation. ... We do some defaulting for abstract Collection classes and * interfaces, to avoid having to use ...
Read more >AnnotationIntrospector (jackson-databind 2.5.0 API) - FasterXML
Abstract class that defines API used for introspecting annotation-based configuration for serialization and deserialization. Separated so that different ...
Read more >Class AnnotationIntrospector - Adobe Developer
public abstract class AnnotationIntrospector extends Object implements Versioned, ... Returns: Collection of all introspectors starting with this one, ...
Read more >Class AnnotationIntrospector - Red Hat Customer Portal
Abstract class that defines API used for introspecting annotation-based configuration for serialization and deserialization. Separated so that different ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@2is10 Ok. Yes, I hope to solve that one still.
And just in case it might help, there is the
SimpleModule.addAbstractTypeMapping()
that allows specifying a mapping – the reason it could potentially help (if you can think of a concrete subtype) is that although it is not necessary for deserializer to actually work, existence is required: so you could map abstract type to any other subtype for which a valid deserializer could be created (regardless of whether it would actually work if ever called).Or, I guess you could also register bogus custom deserializer, which similarly should never actually get called.
Still, I hope I can fix #2252 itself in future.
Thanks @cowtowncoder!
Note: In my actual code, the abstract
Set
class that triggered the problem was Guava’sImmutableSet
, so I’m personally still invested in a solution to #2252. (I didn’t want to introduce a dependency on jackson-datatypes-collections/guava as a workaround.)