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

Use key type factory methods ahead of ctors #2180

Conversation

tbartley
Copy link

@tbartley tbartley commented Nov 7, 2018

Fixes #2158

Simply swaps the order factory method and String
constructors are searched for in the key type.
Factory methods are now preferred.

@cowtowncoder
Copy link
Member

What is the basis for change? Is this the order used for values too?

Fixes FasterXML#2158

Simply swaps the order factory method and String
constructors are searched for in the key type.
Factory methods are now preferred.
@tbartley tbartley force-pushed the tbartley/give-factory-methods-precedence-over-constructors-in-string-key-type-deserialisers branch from d6a1b6d to 07aca04 Compare July 5, 2019 03:15
@tbartley
Copy link
Author

tbartley commented Jul 5, 2019

That I had this PR going completely slipped my mind. Rebased it now that the unrelated issue I was hitting is merged and it now builds and tests cleanly.

@tbartley
Copy link
Author

tbartley commented Jul 5, 2019

In answer to your question "Is this the order for values too?" - yes, where a single field constructor is present and not itself annotated with @JsonCreator.

If single argument constructor of the same type is present and annotated with @JsonCreator and there's a single argument @JsonCreator annotated factory method then, AFAICT, an exception is thrown (CreatorCollector.verifyNonDup:311)

                        throw new IllegalArgumentException(String.format(
                                "Conflicting %s creators: already had %s creator %s, encountered another: %s",
                                TYPE_DESCS[typeIndex],
                                explicit ? "explicitly marked"
                                        : "implicitly discovered",
                                oldOne, newOne));

@cowtowncoder
Copy link
Member

Ok thanks -- I will need to re-read this, and will put it on my todo list.

@tbartley
Copy link
Author

tbartley commented Jul 18, 2019 via email

@cowtowncoder
Copy link
Member

Hmm. Ok. This gets tricky. So, BasicDeserializerFactory comment actually says:

        // Important: first add factory methods; then constructors, so
        // latter can override former!
        _addDeserializerFactoryMethods(ctxt, beanDesc, vchecker, intr, creators, creatorDefs);
        if (beanDesc.getType().isConcrete()) {
            _addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators, creatorDefs);
        }

which would suggest constructors are (or were intended) to have precedence over factory methods. And as far as I can tell, conflicts only matter with explicit (annotated conflicts) -- in case of implicitly found creators, later ones override earlier ones.

Given this, I don't think I want to change the lookup order: existing order has been default order since now so there need to be some really good reason to change it.

However. One thing I could add would be to check for explicit annotation (@JsonCreator), to determine if one has been explicitly specified. Problem with this would be that for some types creator to use for Keys might be different from that for values.
Alternatively it would be possible to create new method in AnnotationIntrospector to either:

  1. Handle lookup for markers for possible key deserializer candidates OR
  2. Resolve case where 2 alternate Creators are found (and in case of more than 2, call it pair-wise).

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.

@JsonCreator ignored when deserializing map keys
2 participants