-
-
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
Allow @JsonMerge
with Custom List
#4784
Conversation
Feel free to close! Wrote a PR in case we might want to add this to test cases, |
As per my comments elsewhere, I don't think |
Note It might be tricky, come to think of it, as there's need for a deserializer to handle merging, I think. Construction of which should not fail unless... hmmh. |
@JsonMerge
with Custom List@JsonMerge
with Custom List
throw new IllegalArgumentException("Cannot find a deserializer for non-concrete Collection type "+type); | ||
// [databind#4783] Since 2.19, Allow `@JsonMerge` with Custom Collection extension. | ||
// Let's not throw exceptino so instantiation can happen downstream | ||
if (_canMapSuperInterfaceAsAbstractCollectionType(type, config)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually... while I understand the intent here, I don't think this check buys as anything: we already know type implements Collection
, which is mappable.
So how about this: looking at what AbstractDeserializer.constructForNonPOJO(beanDesc);
maybe we should just always construct that -- so remove check for
if (type.getTypeHandler() == null) {
and just do it if we cannot map abstract type. And see how that works wrt our test suite and issue here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried actually, it fails with below exception.
I checked what gets created inside AbstractDeserializer
and almost nothing to actually deserialize anything.
The intent behind the // do nothing
current approach was to create StringCollectionDeserializer
/ CollectionDeserializer
below starting at line 862.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.fasterxml.jackson.databind.tofix.JsonMergeWithCustomCollection4783Test$MyListCustom` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 11] (through reference chain: com.fasterxml.jackson.databind.tofix.JsonMergeWithCustomCollection4783Test$MergeCustomStrin
```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But wouldn't hurt showcasing here! Lemme just make the suggested change so we both can see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, you can see checks are failing with the same exceptions.
Took a shot at solving this issue. PS: Looking at current implementation I am not sure if we have this merged to 2.18 (seems a bit risky?) |
public class JsonMergeWithCustomCollection4783Test | ||
{ | ||
|
||
private static class MyArrayListJDK<T> extends ArrayList<T> implements List<T> { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for implements List<T>
, already does via ArrayList<T>
.
static class MergeCustomStringList { | ||
@JsonMerge | ||
@JsonProperty | ||
public MyListCustom<String> values = createCustomStringList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think helper method needed? Just create directly with new MyArrayListCustom<>()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you want to add values in this method?
{ values.add("a"); } | ||
} | ||
|
||
static <T> MyListCustom<T> createCustomStringList() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really needed as per above (but if it was, should parameterize with String
to align with name.
static class MergeMyCustomLongList { | ||
@JsonMerge | ||
@JsonProperty | ||
public MyCustomLongList<String> values = createCustomLongList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmmh. If its "Long" list, shouldn't it contain Long
values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so, I think we can simplify the fix by using AbstractDeserializer
for all cases, and see how that works.
I agree, bit risky for 2.18, based on experience. So let's target 2.19 EDIT: I notice pr is against 2.18. We can consider that if necessary. |
I didn't think this was an urgent issue actually, so leaning toward 2.19. I was even thinking to close(to postpone) this one since you got so much going on now @cowtowncoder |
@JooHyukKim Ok thanks. I think we are good -- let's try getting this done, I think it is a valid problem to solve. I'll see why the test failures occur... |
Ahhh. Ok, so that'd be too easy -- things won't work because
and it can't really, since we need method like one from
for merging to actually work. So basically we need a proper Let me try a simple change to see what happens if we simply remove the check for abstract altogether. |
Well look at that -- tests actually pass. But probably need a test for non-merging case, to see how error handling works (when trying to deserialize abstract collection without merging) |
@JooHyukKim Ok so it appears fix might be surprisingly simple: just basically remove the "is it abstract -> fail" check. Love when this happens. :) |
Due to simplicity of the fix, I think 2.18 might be fine after all. |
Interestinnggg :))) |
Minor tweak: remove change wrt Map defaulting: will do that for 2.19, to reduce risk for 2.18.2. |
To address #4783
Hopefully it's okay to add to 2.18