jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

@JsonPropertyOrder partially ignored when @JsonUnwrapped is used.

Open presto9292 opened this issue 8 years ago • 8 comments

Following is a minimal example, as you can see the order given in @jsonpropertyorder is not respected for values that are coming from the @jsonunwrapped object

https://gist.github.com/presto9292/8a24329949cb66ddb03ebc02bc153eee

presto9292 avatar Jun 19 '17 12:06 presto9292

Actual result {"value2":2,"value1":1,"value3":3,"value4":4}

Expected result {"value4":4,"value3":3,"value2":2,"value1":1}

presto9292 avatar Jun 19 '17 12:06 presto9292

True, unwrapped properties are not included in ordering, since they are not really known by enclosing serializer as regular properties. And specifically, as things are, will be output as a block of properties per contained, so even if known they can not be reordered separately. Perhaps something could be done with Jackson 3.x once we get there.

cowtowncoder avatar Jun 21 '17 05:06 cowtowncoder

A possible workaround would be using Lombok's @Delegate along with @JsonIgnore, as pointed out in this StackOverflow answer.

While @JsonIgnore will ensure the property is not serialized, @Delegate will tell Lombok to generate delegate methods that forward the call to field properties.

cassiomolin avatar Sep 24 '19 14:09 cassiomolin

Problem is @Delegate does not support recursion which breaks this solution

vedgunjan avatar Jun 25 '21 02:06 vedgunjan

+1 for this issue

phraktle avatar Oct 06 '21 20:10 phraktle

We were trying to output sorted JSON strings to compare in tests. For that case, interestingly enough we could do slight workaround


class Parent {
   String b;
   @JsonUnwrapped
   Child child;

   //getter and setters
}

class Child {
   String a;
   String z;

   //getter and setters
}

...

		final ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
		objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

		final Child child = new Child();
		child.a = "a";
		child.z = "z";
		final Parent parent = new Parent();
		parent.child = child;
		parent.b = "b";

		final String results = objectMapper.writeValueAsString(parent);
		System.out.println(results); //prints {"b":"b","a":"a","z":"z"}

		//this is actually converted to a Map
		final Object parentAsObject = objectMapper.readValue(results, Object.class);
		final String results2 = objectMapper.writeValueAsString(parentAsObject);
		System.out.println(results2); //prints {"a":"a","b":"b","z":"z"}




nathanukey avatar Oct 29 '25 11:10 nathanukey

My guess is that sorting propoerties from JsonUnwrapped data would be under-the-hood-similar to Map case above.

If so, question is it worth the trouble? (Would for sure be difficult enough to cover complex cases)

JooHyukKim avatar Oct 30 '25 00:10 JooHyukKim

There are fairly significant problems in implementing sorting: "parent" serializer has no visibility into unwrapped properties. Fixing that fundamental problem is something I hoped to do for 3.0 but never found time. Since it almost certainly requires changes to (mostly internal) APIs, interaction between ValueDeserializers, I think chances of this happening are low.

This for attempting to explicitly order "unwrapped" properties with @JsonPropertyOrder.

FWTW.

cowtowncoder avatar Oct 30 '25 01:10 cowtowncoder