Skip to content
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

Add MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER to use Creator properties' declaration order for sorting #4580

Closed
cowtowncoder opened this issue Jun 14, 2024 · 9 comments
Labels
2.18 3.x Issues to be only tackled for Jackson 3.x, not 2.x

Comments

@cowtowncoder
Copy link
Member

Describe your Issue

Although Creator-provided properties are sorted before other properties, esp. if MapperFeature.SORT_CREATOR_PROPERTIES_FIRST is enabled.

But if MapperFeature.SORT_PROPERTIES_ALPHABETICALLY is enabled, properties of single Creator are still sorted alphabetically. This is probably not what is wanted, at least for Records.

So, we have 2 possibilities:

  1. If SORT_CREATOR_PROPERTIES_FIRST is enabled, retain order of all Properties-based Creators (unless there is explicit @JsonPropertyOrder)
  2. Only retain full ordering for Record Creators

Further we could add a new MapperFeature to control above cases.
Something like MapperFeature.RETAIN_ORDER_OF_CREATOR_PROPERTIES?

NOTE: this becomes more obvious with 3.0 when SORT_PROPERTIES_ALPHABETICALLY will be enabled by default.

@cowtowncoder cowtowncoder added the to-evaluate Issue that has been received but not yet evaluated label Jun 14, 2024
@JooHyukKim
Copy link
Member

JooHyukKim commented Jun 16, 2024

Can we label this 3.x? Since SORT_PROPERTIES_ALPHABETICALLY default setting changed, this also something to be addressed pre-Jackson-3

Regarding the mentioned 2 possibilities, would it be possible to support (and feasible to implement) both, if both of them are default behavior in 2.x?

@cowtowncoder
Copy link
Member Author

I don't think it absolutely has to be 3.x, although if it turns out difficult to do, or controversial, can consider 3.x only.
Same problem affects 2.x when user enables SORT_PROPERTIES_ALPHABETICALLY -- some users may like it, others possibly not.

@JooHyukKim
Copy link
Member

Okay, I took some time on thinking. My ideas are...

First, let's not introduce MapperFeature.RETAIN_ORDER_OF_CREATOR_PROPERTIES, which will double the number of case scenarios to already existing 4 cases (SORT_PROPERTIES_ALPHABETICALLY x SORT_CREATOR_PROPERTIES_FIRST)

Second, no need to proactively resolve this issue. I would say let's just wait and see, until we have enough opinions.

We don't have many requests/issues regarding current issue (except #3900). This is not enough to come up with best usage cases going further 2.18 or 3.x.

@cowtowncoder
Copy link
Member Author

I guess that's fair enough. I agree that we don't want too many on/off features, where number of combinations grows rapidly.

So let's keep this open and see if we come up with better ideas; but not work on this before having clearer idea of what should be achieved (and with what configuration).

@pjfanning
Copy link
Member

For 3, I definitely want to have Java Records, Scala Case Classes and Kotlin equivalent default to using the defined order in the constructor (creator). It's a pity that MapperFeature.SORT_PROPERTIES_ALPHABETICALLY is a boolean. Could we deprecate it and in Jackson 3, we can add a new config option that allows multiple values.

  • no sorting (or whatever we want to call how Jackson 2 works by default)
  • sort alphabetically in all cases
  • sort alphabetically for fields/methods but use defined order for creator properties

@cowtowncoder
Copy link
Member Author

Yes, on/off features are tricky. Unfortunately they are also very convenient to add -- adding Enum valued versions is tons more work with plumbing.

But I like the idea of a smaller set of consistent options. I guess one possibility would be to define a handler interface (BeanPropertySorter?) that is configurable.

I suspect that for 2.x we may still want to go with another MapperFeature, however, to provide for possibility of supporting generally useful sorting combinations. Even if in awkward way.
And the for 3.0 implement better version.

I guess alternatively we could add abstraction even in 2.x but make it be built from MapperFeautures.

Given that there is no -- I think -- change in behavior for 2.18, I think I'll tag this for 2.19 for now. To indicate we hope to tackle it after 2.18, unless someone has time and itch to do it sooner (can always change labels, it's just intent not commitment).

@cowtowncoder cowtowncoder added 2.19 Issues planned at 2.19 or later and removed 2.18 to-evaluate Issue that has been received but not yet evaluated labels Jun 18, 2024
@pjfanning
Copy link
Member

If we are keeping MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, can we change its result then to mean to only affect properties that are not part of the creator properties. The creator properties come first.

Can I also ask about whether we support specifically a locale for the sort? Alphabetic sort order is locale specific.

https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/text/Collator.html

@cowtowncoder
Copy link
Member Author

cowtowncoder commented Jun 19, 2024

If I remember correctly, we just use whatever String.compareTo() supports, i.e. not specifying Locale.

As to changing SORT_PROPERTIES_ALPHABETICALLY, I don't want to change semantics of existing settings for 2.x. So likely it'd need to be something that only affects Creator properties (something like "retain creator properties declaration order"; defaulting to false).
Granted existing piece-wise SORT_PROPERTIES_ALPHABETICALLY is odd setting (wrt sorting Creator properties as a block, but then within). But if I've learned something it is that changing semantics of settings (esp. defaults) tends to break some usage somewhere.

EDIT: existing names of features do begin with SORT_xxx tho, so need to think of suitable name -- I think I know semantics

@cowtowncoder cowtowncoder added 2.18 and removed 2.19 Issues planned at 2.19 or later labels Jun 19, 2024
@cowtowncoder cowtowncoder changed the title Consider retaining Creator-provided property order for serialization (esp for Record) Add MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER to use Creator properties' declaration order for sorting Jun 19, 2024
@cowtowncoder
Copy link
Member Author

Ok. I think that for 2.x, addition of MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER works: enabling of it keeps Creator properties sorted before others, and in declaration order.

It seems to me there are 3 sensible property sorting choices -- and then 4th one we currently have for 3.0:

  1. Full lexicographic (~= alphabetic) sorting of all properties
  2. Creator properties first (in declaration order), other properties in lexicographic order
  3. Creator properties first (in declaration order), other properties in whatever order we happen to get them
  4. (current 3.0 logic) Creator properties first (in lexicographic order), other properties separately in their lexicographic sorting

So: 2.x default is (3), 3.0 default is (4), as of now.

But I would prefer (2) as default for 2.0, and I think this would also allow dropping of 2.x-only MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER that is being added for this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.18 3.x Issues to be only tackled for Jackson 3.x, not 2.x
Projects
None yet
Development

No branches or pull requests

3 participants