[JAVA-5110] Double inheritance with generic types stops recognizing the class of the type Created: 16/Aug/23  Updated: 21/Aug/23

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

Type: Bug Priority: Major - P3
Reporter: 404GATEAWAY N/A Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JAVA-4578 Java driver cannot handle Deeper Poly... Backlog
Epic Link: Investigate our POJO implementation
Quarter: FY24Q2
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Summary

I'm building an application and encountered in an issue while configuring my POJO class
Suggestion that inherit 2 more classes, and first one "Entry" contains an ID field of generic type of the class.

 

org.bson.codecs.configuration.CodecConfigurationException: An exception occurred when encoding using the AutomaticPojoCodec.
Encoding a Suggestion: 'ru.minecomplex.bot.discord.suggest.Suggestion@317cb54d' failed with the following exception:
Failed to encode 'Suggestion'. Encoding '_id' errored with: Can't find a codec for class java.lang.Object.
A custom Codec or PojoCodec may need to be explicitly configured and registered to handle this type.
        at org.bson.codecs.pojo.AutomaticPojoCodec.encode(AutomaticPojoCodec.java:53) ~[Bots.jar:?]
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) ~[Bots.jar:?]
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) ~[Bots.jar:?]
        at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:403) ~[Bots.jar:?]
        at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:375) ~[Bots.jar:?]
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) ~[Bots.jar:?]
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) ~[Bots.jar:?]
        at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:77) ~[Bots.jar:?]
        at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59) ~[Bots.jar:?]
        at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:147) ~[Bots.jar:?]
        at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138) ~[Bots.jar:?]
        at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:61) ~[Bots.jar:?]
        at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:247) ~[Bots.jar:?]
        at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99) ~[Bots.jar:?]
        at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:450) ~[Bots.jar:?]
        at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72) ~[Bots.jar:?]
        at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:226) ~[Bots.jar:?]
        at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269) ~[Bots.jar:?]
        at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:435) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:261) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:72) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:205) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:196) ~[Bots.jar:?]
        at com.mongodb.operation.OperationHelper.withReleasableConnection(OperationHelper.java:501) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:196) ~[Bots.jar:?]
        at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:71) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:216) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1053) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoCollectionImpl.executeReplaceOne(MongoCollectionImpl.java:611) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoCollectionImpl.replaceOne(MongoCollectionImpl.java:587) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.MongoRepository.save(MongoRepository.java:73) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.add(AbstractRepository.java:60) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.add(AbstractRepository.java:55) ~[Bots.jar:?]
        at ru.minecomplex.bot.discord.suggest.SuggestionManager.createSuggestion(SuggestionManager.java:39) ~[Bots.jar:?]
        at ru.minecomplex.bot.discord.suggest.SuggestionCommands.onModalInteraction(SuggestionCommands.java:68) ~[Bots.jar:?]
        at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:442) ~[Bots.jar:?]
        at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96) [Bots.jar:?]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88) [Bots.jar:?]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70) [Bots.jar:?]
        at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:176) [Bots.jar:?]
        at net.dv8tion.jda.internal.handle.InteractionCreateHandler.handleInternally(InteractionCreateHandler.java:108) [Bots.jar:?]
        at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:39) [Bots.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:1014) [Bots.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:900) [Bots.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:878) [Bots.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:1053) [Bots.jar:?]
        at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385) [Bots.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276) [Bots.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996) [Bots.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755) [Bots.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108) [Bots.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64) [Bots.jar:?]
        at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45) [Bots.jar:?]
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Failed to encode 'Suggestion'. Encoding '_id' errored with: Can't find a codec for class java.lang.Object.
        at org.bson.codecs.pojo.PojoCodecImpl.encodeValue(PojoCodecImpl.java:182) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.encodeProperty(PojoCodecImpl.java:168) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.encodeIdProperty(PojoCodecImpl.java:147) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.encode(PojoCodecImpl.java:95) ~[Bots.jar:?]
        at org.bson.codecs.pojo.AutomaticPojoCodec.encode(AutomaticPojoCodec.java:50) ~[Bots.jar:?]
        ... 53 more
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.lang.Object.
        at org.bson.internal.CodecCache.getOrThrow(CodecCache.java:57) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:64) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:39) ~[Bots.jar:?]
        at org.bson.codecs.pojo.FallbackPropertyCodecProvider.get(FallbackPropertyCodecProvider.java:38) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PropertyCodecRegistryImpl.get(PropertyCodecRegistryImpl.java:44) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.getCodecFromPropertyRegistry(PojoCodecImpl.java:273) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.specializePojoCodec(PojoCodecImpl.java:258) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.addToCache(PojoCodecImpl.java:239) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.specialize(PojoCodecImpl.java:79) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecImpl.<init>(PojoCodecImpl.java:60) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecProvider.getPojoCodec(PojoCodecProvider.java:85) ~[Bots.jar:?]
        at org.bson.codecs.pojo.PojoCodecProvider.get(PojoCodecProvider.java:72) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:57) ~[Bots.jar:?]
        at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:39) ~[Bots.jar:?]
        at com.mongodb.internal.operation.Operations.createFindOperation(Operations.java:150) ~[Bots.jar:?]
        at com.mongodb.internal.operation.Operations.find(Operations.java:139) ~[Bots.jar:?]
        at com.mongodb.internal.operation.SyncOperations.find(SyncOperations.java:98) ~[Bots.jar:?]
        at com.mongodb.client.internal.FindIterableImpl.asReadOperation(FindIterableImpl.java:221) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:143) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92) ~[Bots.jar:?]
        at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:39) ~[Bots.jar:?]
        at com.google.common.collect.Sets.newHashSet(Sets.java:224) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.MongoRepository.findAll(MongoRepository.java:63) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.lambda$loadAll$2(AbstractRepository.java:88) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.action(AbstractRepository.java:148) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.loadAll(AbstractRepository.java:86) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.AbstractRepository.load(AbstractRepository.java:34) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.repository.MongoRepository.load(MongoRepository.java:54) ~[Bots.jar:?]
        at ru.minecomplex.bot.discord.suggest.SuggestionManager.load(SuggestionManager.java:25) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.manager.ManagersImpl.lambda$enableAll$2(ManagersImpl.java:35) ~[Bots.jar:?]
        at java.util.ArrayList.forEach(ArrayList.java:1511) ~[?:?]
        at ru.minecomplex.core.impl.manager.ManagersImpl.enableAll(ManagersImpl.java:33) ~[Bots.jar:?]
        at ru.minecomplex.core.impl.CoreImpl.enable(CoreImpl.java:102) ~[Bots.jar:?]
        at ru.minecomplex.core.api.Network.enable(Network.java:70) ~[Bots.jar:?]
        at ru.minecomplex.bot.standalone.Standalone.onEnable(Standalone.java:46) ~[Bots.jar:?]
        at ru.minecomplex.bot.standalone.Standalone.main(Standalone.java:34) ~[Bots.jar:?]

 

 

My Suggestion.class is:

public class Suggestion extends Creatable<Integer> {
 
    private long messageId;
    private String text;
 
    @BsonCreator
    public Suggestion(@BsonId Integer id) {
        super(id);
    }
 
}

My Creatable.class is:

 

public abstract class Creatable<T> extends Entry<T> {
 
    protected String owner;
    protected long createdAt = System.currentTimeMillis();
 
    public Creatable(T id) {
        super(id);
    }
 
}
 

My Entry.class is: 

 

public abstract class Entry<K> implements Serializable<K> {
 
    protected K id;
 
    public Entry(K id) {
        this.id = id;
    }
 
}
 

My Serializable.class is:

@BsonDiscriminator
public interface Serializable<K> {
 
    K getId();
 
}

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

How to Reproduce

Create a POJO class with double inheritance of classes with generic type containg field of it and try to save it.

Steps to reproduce. If possible, please include a Short, Self Contained, Correct (Compilable), Example.

Additional Background

When I remove the Creatable class inheritance and add it's all fields + id constructor to the Suggestion.class , it solves the problem. So this might give you the all needed information to fix that

Please provide any additional background information that may be helpful in diagnosing the bug.



 Comments   
Comment by Tom Selander [ 21/Aug/23 ]

sigamatute@gmail.com This appears to be a bug, we have added this to our backlog.

Comment by 404GATEAWAY N/A [ 17/Aug/23 ]

jeff.yemin@mongodb.com I tried all different ways, it fixes only if I make one inheritance with generic type 

Comment by 404GATEAWAY N/A [ 16/Aug/23 ]

Forgot to add the @Getter to the provided code, class Entry creates the getter for "K id" field

@Getter
public abstract class Entry<K> implements Serializable<K> {
 
    protected K id;
 
    public Entry(K id) {
        this.id = id;
    }
 
}
 

Comment by Jeffrey Yemin [ 16/Aug/23 ]

Hi sigamatute@gmail.com, what happens if you keep the Entry superclass but remove the Serializable interface, adding the K getId() method to Entry instead?

Comment by 404GATEAWAY N/A [ 16/Aug/23 ]

MongoRepository#save method that is in the stracktrace of the error and the way I save an object: 

@Override
public void save(V value) {
    collection.replaceOne(Filters.eq("_id", value.getId()), value, new ReplaceOptions().upsert(true).build());
} 

Comment by PM Bot [ 16/Aug/23 ]

Hi sigamatute@gmail.com, thank you for reporting this issue! The team will look into it and get back to you soon.

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