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

FasterXML/jackson-databind#1296 @JsonIncludeProperties #2771

Merged
merged 16 commits into from
Jul 24, 2020

Conversation

sp4ce
Copy link
Contributor

@sp4ce sp4ce commented Jun 18, 2020

Fix for #1296 (@JsonIncludeProperties)

Serialization

Serialization
@sp4ce
Copy link
Contributor Author

sp4ce commented Jun 18, 2020

This PR is not for being merged as-is, it's just to get early input

@sp4ce sp4ce changed the title FasterXML/jackson-databind#1296 [WIP] FasterXML/jackson-databind#1296 Jun 18, 2020
@sp4ce sp4ce changed the title [WIP] FasterXML/jackson-databind#1296 FasterXML/jackson-databind#1296 Jun 21, 2020
@sp4ce
Copy link
Contributor Author

sp4ce commented Jun 21, 2020

Removing the [WIP] as this is now ready

@sp4ce sp4ce changed the title FasterXML/jackson-databind#1296 FasterXML/jackson-databind#1296 @JsonIncludeProperties Jun 22, 2020
@cowtowncoder
Copy link
Member

Ok this looks pretty good, all around; only missing piece I noticed was that AnnotationIntrospectorPair also needs additions; question of how to combine settings might be interesting -- I assume non-null answer from primary should be used as-is; and only if it returns null, check out secondary.
This leads to bigger question of how to express things.

So: I wonder if there is need to indicate "just include all" case; at first I assumed so (from annotations), but I guess that is simply equivalent to leaving out annotation altogether.
However, I can see some potential use for specifying empty set, to mean "include no properties", resulting in { } serialization (except if there might be Type Id or Object Id or such).

I also mentioned possibility of adding enabled property, to use with mix-ins, to override annotation use. It may not really be needed yet; and it is possible to add after the fact, I think, given that there is Value object (which I think is a good idea).

Another possible change could be to pass JsonIncludedProperties.Value itself, instead of Set<String>, when passing things to deserializers (and not just by AnnotationIntrospector): the reasons to do so would be for expansion. I am not sure that would be valuable now, and it's probably not good to over-design for possible unknown future use.
But I like definition and use of Value at least during introspection. I have found this to be useful pattern.

I'll think about these things a bit more, but so far I think this looks pretty good!

@cowtowncoder
Copy link
Member

Ok, so: AnnotationIntrospector... It is used to allow a few different use cases: original use was to allow support for both Jackson and JAXB annotations, for mostly overlapping usage.
Since then also allows various modules to change aspects usually configured via annotations, but that may come from other sources too (f.ex Scala and Kotlin modules inferring implied @JsonCreator for primary constructors).

In case of multiple introspectors all of them are arranged in logical chain, pair-wise, with precedence. For most annotations, primary introspectors is called to see if it finds an answer (for, say, property name via @JsonProperty); if yes, that is used, if not, secondary is asked.
In some cases it is also possible that both are checked, and if both return existing value(s), those are combined: this is the case for @JsonIgnoreProperties, which are additive.
But it need not necessarily be the case for @JsonIncludeProperties.

So, distinction between "not found" and "found empty" is often significant; and I think it may be important here too because not having annotation essentially means no-inclusion restrictions. But I think it looks like it depends on whether choice of both introspectors providing answer should be:

  1. Primary one wins (just take first existing setting, use that): if so, AnnotationIntrospector must indicate "no annotation" with null (... or marker within Value object to indicate virtual "nothing" instance)
  2. Combine the answers: if so, both values are taken and merged, no null value should be used since there is combination logic anyway.

Does this make more sense?

/**
* @since 2.12
*/
public abstract BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(note to self, mostly)

Makes sense to use different name, I think, withPropertyInclusions() (to indicate both ignoral and/or inclusion contained), for the new method.

Set<String> prev = contextual._includableProps;
if (prev != null && included != null) {
Set<String> newIncluded = new HashSet<>();
// Make the intersection with the previously included properties.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure if this is the right default: seems like there would be 3 possibilities:

  1. Intersection (must be in class defaults/annotations AND property)
  2. Union (add anything property defines)
  3. Overwrite/replace (use whatever property defines)

Now, adding "mode" or something in JsonIncludeProperties (and .Value) would allow specifying these modes easily if we want to. But even without adding that, I wonder what the most likely expected use case would be?
My guess would have been either (3) or (2).

@cowtowncoder
Copy link
Member

As per my note on annotations PR (FasterXML/jackson-annotations#174), I am ready to merge the PRs and get this in for 2.12! Excited to add the feature, given its popularity.

@cowtowncoder cowtowncoder merged commit d9c0332 into FasterXML:2.12 Jul 24, 2020
@cowtowncoder
Copy link
Member

Merged, changed in places. But now need to figure out why there is one fail for Guava Multimaps wrt ignoral -- probably something to do with this change (maybe something about constructor changes)

@cowtowncoder
Copy link
Member

After looking at the issue, not a problem with this PR but changes I made afterwards. :)

@sp4ce
Copy link
Contributor Author

sp4ce commented Jul 29, 2020

Ok glad to hear it, I saw your message in #1296 but could not answer. If you need that I do some follow up on the PR, I can have a look as well.

@cowtowncoder
Copy link
Member

@sp4ce thanks! I think we are good, I found the specific problem with changes I made (to add MapperConfig as argument for an existing method in AnnotationInstropector [or rather, overload])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add @JsonIncludeProperties(propertyNames) (reverse of @JsonIgnoreProperties)
2 participants