I’ve been working with the Java Sync Driver, and I’ve an issue where I use chainable pattern for my POJOs.
public abstract class Model<T_ extends Model<T_>> {
...
public abstract T_ setId(String id); // and similar other common setters.
...
}
I have the above base class for my models, and every model extends this class. This provides me a static monolithic common methods interface where I can simply call this to find documents or items as;
final var subserver = Model.findOne(filters(eq(“_id”, userData.getSubserverId())), SubServer.class);
and etc. But this introduces this exception when I use MongoCodecs so I can fetch POJOs from the collection with;
getClient().getDatabase(getDatabaseName()).getCollection(getCollectionName(), getModelClass())...;
the exception is;
ClassCastException: “class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to class java.lang.Class (sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl and java.lang.Class are in module java.base of loader ‘bootstrap’)”
this occurs at org.bson.codecs.pojo.TypeData.java@84;
private static <T> void getNestedTypeData(final TypeData.Builder<T> builder, final Type type) {
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
TypeData.Builder paramBuilder = TypeData.builder((Class) pType.getRawType());
for (Type argType : pType.getActualTypeArguments()) {
getNestedTypeData(paramBuilder, argType);
}
builder.addTypeParameter(paramBuilder.build());
} else if (type instanceof WildcardType) {
builder.addTypeParameter(TypeData.builder((Class) ((WildcardType) type).getUpperBounds()[0]).build());
} else if (type instanceof TypeVariable) {
builder.addTypeParameter(TypeData.builder(Object.class).build());
} else if (type instanceof Class) {
builder.addTypeParameter(TypeData.builder((Class) type).build());
}
}
at the first else if (for wildcard type). this block assumes the wildcard’s upper bound is always a Class, but in my case it’s a ParameterizedType due to the self-referencing generic (T extends Model)
Just wanted to give a feedback about this behavior.
For the ones that are going to tell me that I should not use the generic chaining pattern for this use case; I will introduce the common types into the base model class so I can drop the generics (but this will break my getter/setter usages) as it is the only solid workaround i can think of.