You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Pojo Codec fixes with sub-classes and bson creator
This commit tries to fix a few issues:
1. It was not possible to overload a getter in a sub-class and make the
type more specific (covariant overload). For example, attempting to
serialize Bar would fail:
```
// Assume there are setters here as well...
class Foo {
public Number getNumber() { /*...*/ }
}
class Bar extends Foo {
@OverRide
public Long getNumber() { /*...*/ }
}
```
This was due to bridge methods not getting picked up, so even though
Method#getDeclaredMethods is documented to return methods only from the
super class, the Java compiler inserts a bridge method in the sub-class
(Bar in this case) for these covariant overrides for legacy interop.
2.a. It was not possible to use a more specific type in a getter, but a
more general type in the setter/constructor/static factory method. For example:
```
class Foo {
public ImmutableList<String> getNames() { /*...*/ }
// Mutable class
public void setNames(List<String> names) { /*...*/ }
// or immutable class (both didn't work)
@BsonCreator
public Foo(@BsonProperty("names") List<String> names) { /*...*/ }
}
```
The first issue was that strict type equality was enforced. This is a
pretty common pattern that should be allowed though - it's typically a
bad idea to accept such a specific class in your constructor/setter.
In my case, I'm creating my domain models with Immutables, so the
generated immutable class will override my getter that returns
`List<T>` to return `ImmutableList<T>`.
The second issue was that various collections were boxed to specific
implementations like ArrayList/HashMap/HashSet. Doing this in TypeData
caused quite a few problems. The main being it was no longer possible to
understand the type hierarchy (ImmutableList does not extend ArrayList,
but it safely implements List). The ArrayList/HashMap/etc selection
happens in collection codec as an implementation detail. I think this is
a bit cleaner.
3. It was not possible to use immutable collections like Guava's
ImmutableList. By fixing the above issues, it works now. Note that we
still can't use ImmutableList as an argument that's accepted, but that's
a case where it's reasonable to provide a custom codec implementation
since there's no way we can do that automatically.
4. @BsonCreator annotations were only searched for in the target class,
but not any super classes. It's relatively common to have an abstract
base class host all of the static factory methods for the concrete
subtypes, so this allows for that pattern. I do the above, but in
addition, some of my domain models are generated through Immutables
where I don't have the ability to inject annotated static factory
methods.
-----
I moved code around a bit for better locality and some re-usability. In
particular with PropertyReflectionUtils, and TypeData having a few
methods of extracting the types out of methods/fields/etc.
I tried to add test cases for all of the above things - they all failed
prior to these modifications. All other existing bson tests pass.
JAVA-2612
0 commit comments