[JAVA-3815] Pojo Codec does not detect property models on extended interfaces Created: 14/Aug/20  Updated: 10/Mar/23

Status: Backlog
Project: Java Driver
Component/s: POJO
Affects Version/s: 4.1.0
Fix Version/s: None

Type: New Feature Priority: Major - P3
Reporter: Joseph Florencio Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Epic Link: Investigate our POJO implementation
Quarter: FY23Q4, FY24Q2
Backwards Compatibility: Minor Change

 Description   

I created a pull request, so copying the text from that:

If we have an interface like:

public interface SampleInterface {
 int getFirst();
 String getSecond();
}

which is implemented as:

public abstract class SampleImplementor implements SampleInterface {
 public abstract boolean isThird();
}

and has a concrete implementation that's called `SampleImplementorImpl`.
When `PojoBuilderHelper` goes to create the property models, it only checks
for methods on the current class and super classes - not interfaces. In
the above example, this means the property model will only have "third" entry -
no "first" or "second" property model. Today, you can manually get around that by
creating a @BsonCreator by hand:

public abstract class SampleImplementor implements SampleInterface {
 @BsonCreator
 public static SampleImplementor newInstance(
 @BsonProperty("first") int first,
 @BsonProperty("second") String second,
 @BsonProperty("third") boolean third) {
 return new SampleImplementorImpl(first, second, third);
 }
 
public abstract boolean isThird();
}

The presence of the `@BsonProperty` on the `@BsonCreator` method will
create the property models. Conversely though, if you want to leverage a
`Convention` implementation to dynamically create a `InstanceCreator`
that knows how to find `SampleImplementorImpl` above, you won't be able
to. `InstanceCreator` is only provided properties for which
`PropertyModel` exists, so above, since `PojoBuilderHelper` didn't
discover the interface fields, and there is no exposed API to add
property models, your `InstanceCreator` will never be provided the
`first` and `second` fields present on the interface.

Simply put, if you provide the pojo codec a class that is not concrete,
extends an interface for methods, and does not have a `@BsonCreator`
annotation, there is no way to implement a `InstanceCreator`
implementation that works for the non concrete class. You get stuck in
a place where the class can serialize since the concrete implementation
`SampleImplementorImpl` is provided at runtime, but then you have no way
to deserialize it since usages in the code only reference `SampleImplementor`.

We've worked around this problem for years and created 700+ hand written
`@BsonCreator` annotations, so at this point I want to fix actual the problem.

This fix is relatively straight forward: Update `PojoBuilderHelper` to
scan implementing classes and interfaces, which provides a fully
populated property model.



 Comments   
Comment by Joseph Florencio [ 14/Jan/21 ]

Just wanted to follow up here, any chance the team can look into this..?

Comment by Joseph Florencio [ 05/Oct/20 ]

Hey Jeffrey,

No worries. I'm currently not blocked since I created a fork of the MongoDB Java Driver with my PR above that my organization is using. Would be ideal to have some type of solution eventually so we don't need to be on this fork permanently though. Generally speaking, I don't think there is an alternative workaround that doesn't involve forking since adding property models to ClassModelBuilder isn't an exposed API.

Comment by Jeffrey Yemin [ 30/Sep/20 ]

Hi joe@deal.com

First of all, sorry for not responding earlier.

Thanks for reporting the issue to us, and for the pull request. We will look into it as time permits. Until then, do you have a workaround available?

Comment by Joseph Florencio [ 14/Aug/20 ]

PR is here: https://github.com/mongodb/mongo-java-driver/pull/563

Generated at Thu Feb 08 09:00:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.