On Wed, Jan 11, 2017 at 3:45 AM,  <victor.n...@gmail.com> wrote:
> Hi,
>
> I am familiar with the issues
> https://github.com/FasterXML/jackson-databind/issues/265 (i.e., using
> @JsonUnwrapped within a @JsonCreator) and others, but in the end, I couldn't
> find the correct way of using @JsonUnwrapped with @JsonCreator (i.e., I want
> to avoid having mutable objects whose fields are modified by Jackson).
>
> If we take the example from the wiki:
>
> class Location {
>     public final int latitude, longitude;
>
>     public Location(int latitude, int longitude) { ... }
> }
>
>
> class Place {
>     public final String name;
>     @JsonUnwrapped public final Location location;
>
>     @JsonCreator
>     public Place(@JsonProperty("name") String name, ????) { ... }
> }
>
>
> What is the correct way of defining the Place constructor?
>
> If I use:
>
>     @JsonCreator
>     public Place(@JsonProperty("name") String name,
>                  @JsonProperty("latitude") int latitude,
>                  @JsonProperty("longitude") int longitude) {
>         this.name = name;
>         this.location = new Location(latitude, longitude);
>     }
>
>
> Then I get an error from Jackson because it tries, after SUCCESSFULLY
> creating the Place object including its location, to then set the
> @JsonUnwrapped annotated fields and fails because it can't create Location,
> and even if it could, it has already consumed the stream so it can't read
> the proper values for location.

Consumption is not a problem (or, at least, shouldn't), since
buffering will be used automatically for all @JsonUnwrapped fields.

> If I use (expecting Jackson to set the location field using the rest of the
> information from the stream):
>
>     @JsonCreator
>     public Place(@JsonProperty("name") String name) {
>         this.name = name;
>         this.location = null;
>     }
>
>
> Then it also fails because I'm not sure why it can't read the rest of the
> stream (I didn't investigate this too much because I got fed up and thought
> I would come asking here :).
>
> So is there a way to make that work and how?
>
> I am using Jackson 2.7.8 for now because of dropwizard integration, but I
> should be able to use a newer version maybe…

My preferred course would be to just not trying to handle `latitude`
and `longitude`, and instead have a setter for location.
That should work fine; that is, constructor only taking `name`.

Otherwise removing of `@JsonUnwrapped` annotation should work, and you
could instead define something like:

@JsonAnyGetter
public Map<String> stuff() {
   // construct Map with `latitude` and `longitude`
   return mapWithLatLong;
}

I am not sure if it'd be possible to make your attempt work: challenge
is that deserializer for Place really does not have much information
on what is contained within @JsonUnwrapped pojo; handling is too
indirect.
So there is nothing linking properties lat/long passed to creator, and
contents of `Location`, from deserializer perspective.

Still... if you could file an issue, perhaps something could be done
for special case where all properties are handled, so there is nothing
to hand to @JsonUnwrapped handlers, call would be avoided and everyone
would be happy.
This is not fool-proof, even if so, since current handling of
unwrapped values combines ALL potential properties (as they can not be
separated); but could be an improvement.

-+ Tatu +-

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-user+unsubscr...@googlegroups.com.
To post to this group, send email to jackson-user@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to