FasterXML / jackson-databind

General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Excessive rigidity: Hardcoded class reference prevents flexible implementations of Object Id Resolvers in Json

DavidIAm opened this issue · comments

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

I want to adapt an awkward, custom form of self-referencing structure into a (more?) standard one so that other elements of the system can use standard JSOG library to read it. I am unable to write a custom resolver that manages the pattern of using references for a model and pattern like this:

model:

JsonIdentityInfo(generator = JSOGGenerator.class, property = "arbitraryFieldName", resolver=HypotheticalPropertyIdResolver.class)
class Node {
  int arbitraryFieldName;
  Node child;
  Node parent;
}

deserializing structure that looks like

{ "arbitraryFieldName": 5,
  "child": {
    "arbitraryFieldName": 6,
   "parent": 5
  }
}

serialization should look like

{ "@id": 1,
   "arbitraryFieldName": 5,
  "child": {
    "arbitraryFieldName": 6,
   "parent": { "@ref": 1 }
  }
}

Version Information

2.16.1

Reproduction

So when you look at

if (implClass == ObjectIdGenerators.PropertyGenerator.class) {

You see that it checks to see what the generator is (specifically 'PropertyGenerator' here) to change its behavior.

I was unable to make a custom generator to have flexible reading capability (to read the property style reference) and write the JSOG style reference, because the only way to get the property style reference deserialization behavior is to use that specific class - not even a descendent/extension of that class - but THAT CLASS SPECIFICALLY. As a generator, not even resolver. You can imagine my irritation.

Delegating this logic to the implementation (doesn't this belong in the resolver?) so that the implementation chosen can decide what do here to rather than having the abstract Deserializer consider PropertyGenerator utilization a special case to check for when resolving ids is entirely appropriate.

Expected behavior

It seems logical to me that the implementation chosen for the resolver should have the chance to determine the logic by which to determine the id for a record, by calling into it and most of the time being delegated to a default implementation.

Additional context

No response

I won't really have time to dig deeper into this in near future but as always, "PRs are welcome" -- so if anyone has time and itch to try to improve things, I will help.

One tiny thing for which I could accept PR would be to simplify check mentioned to accept subtype; but I am not sure how useful that'd be on its own, given that the handling that follows will construct PropertyBasedObjectIdGenerator instance etc.
If that was something that'd allow you to work around problems, I'd be happy to review and merge that PR.

As to the original reason for rigid logic: if I recall correctly, this was to try to add some level of support for JSOG-style reference-as-JSON-Object (but if and only if it's 1-property Object) -- original Object Id design assumed that references would always be Scalar values (likely JSON Strings but possibly numbers).
But doing that required unfortunate trade-offs as seen here.

I'm working on making a pr for what I'd visualize shoudl work here.