Reputation: 1051
I am trying to use the MongoDB Reactive Streams Java Driver 1.11, moving off https://jongo.org/. It seems to be using https://mongodb.github.io/mongo-java-driver/3.10/. I have a bunch of other registered classes that are working fine. I have looked at Mongodb java: Perist POJO class with generic field, but I do not have the option of migrating all my data to remove the fields with generics. I also don't understand why I'm even seeing this error, since the MultiVal
is not even a top level POJO; it's embedded in AbstractBigObject
. Any help would be appreciated.
Below is the error I am seeing.
org.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'BigObject'. Decoding 'nameToMultiDateVal' errored with: MultipleVal contains generic types that have not been specialised. Top level classes with generic types are not supported by the PojoCodec.
Below are some of my relevant data models:
public abstract class AbstractBigObject {
@BsonProperty
private Map<String, MultiVal<LocalDate>> nameToMultiDateVal = Maps.newHashMap();
@BsonProperty
private Map<String, MultiVal<Double>> nameToMultiDoubleVal = Maps.newHashMap();
...
}
public class BigObject extends AbstractBigObject {
...
}
public class MultiVal<T> {
private List<Val<T>> options;
private Val<T> selected;
...
}
@BsonDiscriminator(key = "type")
public interface Val<T> {
...
}
@BsonDiscriminator(key = "type", value = "dateVal")
public class DateVal implements Val<LocalDate> {
...
}
@BsonDiscriminator(key = "type", value = "doubleVal")
public class DoubleVal implements Val<Double> {
...
}
Below is how I'm setting up my codec registry.
MongoClient mongoClient = MongoClients.create(new ConnectionString(mongoConfig.getUri()));
PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder()
.conventions(ImmutableList.of(CLASS_AND_PROPERTY_CONVENTION, ANNOTATION_CONVENTION))
.register(
BigObject.class,
AbstractBigObject.class,
MultiVal.class)
.register(
ClassModel.builder(Val.class).enableDiscriminator(true).build(),
ClassModel.builder(DoubleVal.class).enableDiscriminator(true).build(),
ClassModel.builder(DateVal.class).enableDiscriminator(true).build())
.automatic(true)
.build();
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(pojoCodecProvider));
mongoDb = mongoClient.getDatabase(mongoConfig.getDbName()).withCodecRegistry(codecRegistry);
So I am storing lots of BigObject
in a Mongo collection. But they are unable to be decoded for the above reason. Short of changing all my data models, what else can I do? Is there any way I can specify the relevant codec(s) myself?
Upvotes: 3
Views: 2300
Reputation: 14688
Can you try to wrap your generic types with concrete types and try again?
class DoubleMultiVal extends MultiVal<Double> {
}
class LocalDateMultiVal extends MultiVal<LocalDate> {
}
and use them in AbstractBigObject
;
@BsonProperty
private Map<String, LocalDateMultiVal> nameToMultiDateVal = Maps.newHashMap();
@BsonProperty
private Map<String, DoubleMultiVal> nameToMultiDoubleVal = Maps.newHashMap();
Upvotes: 2