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

@JsonUnwrapped not supported for Map-valued properties #171

Open
stevenschlansker opened this Issue Feb 20, 2013 · 16 comments

Comments

Projects
None yet
7 participants
@stevenschlansker
Copy link
Contributor

stevenschlansker commented Feb 20, 2013

According to the documentation,

Annotation used to indicate that a property should be serialized "unwrapped"; that is, if it would be serialized as JSON Object, its properties are instead included as properties of its containing Object.

Unfortunately, this seems to work only with bean types, and does not work with Map<String, Object>. Given that bean types are generally completely interchangeable with Maps, it would be very nice if this worked correctly.

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Feb 20, 2013

Hmmh. Unfortunately Maps and POJOs are internally handled rather differently. But I am all for unification if it is technically possible, so limitation is not philosophical, just practical. I suspect that serialization part should be easy enough to make work; deserialization might get trickier?

@stevenschlansker

This comment has been minimized.

Copy link
Contributor Author

stevenschlansker commented Feb 20, 2013

It would be very cool if this worked 😄

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Feb 20, 2013

:-)

One quick question: I assume most users would expect it to work both ways. But I suspect serialization is much easier to make work. Would you find any value in serialization-only impl? (especially initial one)

One more thing: as per this:

http://www.cowtowncoder.com/blog/archives/2011/07/entry_458.html

one can use @JsonAnyGetter/setter to do something possibly similar. One missing pieces is that currently one must have getter (can't use it on Map filed), but that should be easy enough to address.

@stevenschlansker

This comment has been minimized.

Copy link
Contributor Author

stevenschlansker commented Feb 20, 2013

Yes, a serialization-only implementation would solve my immediate use case, although I can see the deserialization as being extremely useful as well.

It does seem that this could potentially be done with serialization-only JsonUnwrapped usage and then JsonAnySetter to handle the deserialization case, although that feels more than a little bit janky to me.

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Feb 20, 2013

Yes my concern is really with unexpected one-way street: unwrapping on way out, but not "wrapping it back" as Map on way back in.

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented May 21, 2014

Ok, I think supporting this would be very useful for CSV, f.ex see FasterXML/jackson-dataformat-csv#25
so maybe I should go back, try to tackle this.

Although, with CSV there are other open questions due to name/index mapping. But still, solving this on databind side could help.

@mmadson

This comment has been minimized.

Copy link

mmadson commented May 27, 2015

+1

1 similar comment
@igorcadelima

This comment has been minimized.

Copy link

igorcadelima commented Jul 1, 2015

+1

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Jul 1, 2015

A related note for anyone who happens upon this issue: one alternative is use of @JsonAnyGetter, which does allow functionality for a single Map.

@igorcadelima

This comment has been minimized.

Copy link

igorcadelima commented Jul 1, 2015

Great! @JsonAnyGetter is exactly what I was looking for. Thanks!

christophercurrie pushed a commit to christophercurrie/jackson-databind that referenced this issue Jul 19, 2015

@cowtowncoder cowtowncoder changed the title JsonUnwrapped does not seem to work correctly with Map typed values @JsonUnwrapped not supported for Map-valued properties Dec 11, 2015

@matthew-pwnieexpress

This comment has been minimized.

Copy link

matthew-pwnieexpress commented Jan 24, 2017

I find this behavior surprising at a conceptual level, since it seems to be contrary to how Jackson behaves in general.

Would I be correct in assuming that this is one of the features that will likely not be in the next Jackson 2.9 release, per the Changes likely to be postponed section?

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Jan 24, 2017

@matthew-pwnieexpress You are correct in that no work is planned for this feature.
I can see how this is unexpected from users perspective: difference is due to technical evolution of backend implementation where Maps and POJOs have very different handling. But conceptually this should not surface quite this strongly, or, if it does, would need to be explained and documented much better.

@henryptung

This comment has been minimized.

Copy link

henryptung commented Mar 21, 2017

@cowtowncoder Given that @JsonAnyGetter and @JsonAnySetter exist, how correct/incorrect would an implementation be to have @JsonUnwrapped imply the other two annotations when used with MapSerializer?

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Mar 22, 2017

@henryptung Interesting thought... hmmh. There is also then the possible question of what if more than one such "any property" is declared.
I guess this is not problematic with POJOs as their properties are somewhat defined and multiples unwrapped POJOs may co-exist; whereas any-x is fallback.

@marceloverdijk

This comment has been minimized.

Copy link
Contributor

marceloverdijk commented Apr 15, 2018

Unfortunately the @JsonAnyGetter does not work (easily) with Kotlin:

class Links(
        @JsonAnyGetter
        val links: Map<String, Link>
) : Serializable

as the annotation needs to put on a method.

!! UPDATE !!

It does work (easily):

class Links(
        @get:JsonAnyGetter
        val links: Map<String, Link>
) : Serializable

@cowtowncoder

This comment has been minimized.

Copy link
Member

cowtowncoder commented Apr 16, 2018

True; as of now (2.9), @JsonAnyGetter must be on method. In theory it could be extended to fields, to allow construction of Map instance. One challenge would be the fact that semantics would be slightly different -- in one case method gets fed key/value pair: that could lead to confusion (unless logic further added to perhaps also allow single Map-argument... but that can lead to another can of worms).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment