@JsonCreator with builder and external type I’d not supported? Why?

30 views
Skip to first unread message

Randy Tidd

unread,
Jul 22, 2019, 3:26:48 PM7/22/19
to jackson-user
I have this case on my current project, we are using the builder pattern and have an embedded generic object that requires an external type id. Based on this code this appears to not be supported and based on true comment this has been an issue since 2012.

https://github.com/FasterXML/jackson-databind/blob/7765422a77991995cd4d11b5ebb31ad96dc69bdd/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java#L818

My question is why this is not supported as it seems to be a pretty straightforward and useful case, and if there is any known workaround or has anyone implemented this themselves? I was going to take a shot at it if there are enough hooks to use a custom deserializer.

Thanks!

Tatu Saloranta

unread,
Jul 22, 2019, 4:09:33 PM7/22/19
to jackson-user
It would definitely be great to get a PR for enabling it (along with
simple unit test to show functioning), if that turns out doable.
As the author I have a feeling there at least was some fundamental
challenge to solve that seemed big enough to scare me... but what do I
know. :-)
(I do not recall details but my guess is that this is due to
implementation of external-property-based (de)serialization being
rather hairy AND due to builder handling also being somewhat...
involved. Rendering combination thereof bit... challenging)

-+ Tatu +-

Randy Tidd

unread,
Jul 23, 2019, 8:12:55 AM7/23/19
to jackson-user
Thank you very much for the quick reply. I've spent a lot of "quality time" on this recently :).

My impression is that support for the builder pattern is somewhat of a 2nd class citizen?  Besides this issue I've noticed a couple of other things while trying to work around it by adding my own custom deserializer(s):

- In my deserialize() method I can't access the parent object with i.e. getParserContext().getParent()

- My parameterized builder constructor seems to be called before all of the properties have been parsed, for example if my document has properties A, B, C, FOO, D, E, F where FOO represents my custom type, the constructor is called with values for A, B and C but nulls for D, E, and F, it's as if it calls the constructor before completing the parsing at the parent level.

I suspect these issues are related and that maybe deserializing with the builder pattern is just sequential and doesn't fully handle all of the nuances of nested documents etc.  This is making me think that implementing this in Jackson is too much to take on ATM for my little project.

Randy

Tatu Saloranta

unread,
Jul 24, 2019, 5:26:47 PM7/24/19
to jackson-user
On Tue, Jul 23, 2019 at 5:12 AM Randy Tidd <tid...@gmail.com> wrote:
>
> Thank you very much for the quick reply. I've spent a lot of "quality time" on this recently :).

Oh excellent. This part could benefit from more TLC so...

>
> My impression is that support for the builder pattern is somewhat of a 2nd class citizen? Besides this issue I've noticed a couple of other things while trying to work

Yes, in the sense that due to historical context (it was sort of
cobbled together by smallish tweaks to "main" deserialization),
instead of maybe more robust design.
But beyond that it is also true that there hasn't been as much
activity by others to improve its handling, for whatever reason.

> around it by adding my own custom deserializer(s):
>
> - In my deserialize() method I can't access the parent object with i.e. getParserContext().getParent()

I'd be interested in seeing why this would happen... so maybe a unit
test would help?
There may be multiple reasons for this happening; there is the
fundamental challenge of "current value" not being available until
Builder builds one but aside from that, chain of parents should be
updated, but perhaps isn't.

> - My parameterized builder constructor seems to be called before all of the properties have been parsed, for example if my document has properties A, B, C, FOO, D, E, F where FOO represents my custom type, the constructor is called with values for A, B and C but nulls for D, E, and F, it's as if it calls the constructor before completing the parsing at the parent level.

This should only happen when closing '}' is encountered, and if not,
sounds like a bug.
Would be interested in looking at problem if it's easy to reproduce
with a unit test?

> I suspect these issues are related and that maybe deserializing
with the builder pattern is just sequential and doesn't fully handle
all of the nuances of nested
> documents etc. This is making me think that implementing this in Jackson is too much to take on ATM for my little project.

I think both of above could probably be tackled, and I'd be happy to
help with those parts. It is quite possible that no one has used the
first feature with builders.
Second part sounds more troubling actually, but nonetheless with a
reproduction I should be able to help. From description behavior
sounds wrong, but in a way that sounds potentially easy to fix (vs.
something that sounds more along "that's unfortunately the way it
works because XYZ").

-+ Tatu +-

>
> Randy
>
> On Monday, July 22, 2019 at 4:09:33 PM UTC-4, Tatu Saloranta wrote:
>>
>> On Mon, Jul 22, 2019 at 12:26 PM Randy Tidd <tid...@gmail.com> wrote:
>> >
>> > I have this case on my current project, we are using the builder pattern and have an embedded generic object that requires an external type id. Based on this code this appears to not be supported and based on true comment this has been an issue since 2012.
>> >
>> > https://github.com/FasterXML/jackson-databind/blob/7765422a77991995cd4d11b5ebb31ad96dc69bdd/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java#L818
>> >
>> > My question is why this is not supported as it seems to be a pretty straightforward and useful case, and if there is any known workaround or has anyone implemented this
>> > themselves? I was going to take a shot at it if there are enough hooks to use a custom deserializer.
>>
>> It would definitely be great to get a PR for enabling it (along with
>> simple unit test to show functioning), if that turns out doable.
>> As the author I have a feeling there at least was some fundamental
>> challenge to solve that seemed big enough to scare me... but what do I
>> know. :-)
>> (I do not recall details but my guess is that this is due to
>> implementation of external-property-based (de)serialization being
>> rather hairy AND due to builder handling also being somewhat...
>> involved. Rendering combination thereof bit... challenging)
>>
>> -+ 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/9bd09736-9117-4a13-a057-147f318fa039%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages