[JAVA-4147] JAVA-3408 breaks AutomaticPojoCodecProvider for nested types Created: 10/May/21  Updated: 27/Oct/23  Resolved: 24/May/21

Status: Closed
Project: Java Driver
Component/s: Codecs
Affects Version/s: 4.0.0
Fix Version/s: None

Type: Bug Priority: Unknown
Reporter: John Murphy Assignee: Ross Lawley
Resolution: Works as Designed Votes: 0
Labels: internal-user
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Case:

 Description   

public class InternalStateEntity<I> {
    private class B {
        public B() { }
    }
    private List<B> b = new ArrayList<>();
    protected InternalStateEntity() {
        b.add(new B());
    }
    public List<B> getB() {
        return b;
    }
}
 
public class MongoStateEntity<K> extends InternalStateEntity<ObjectId> {
    public MongoStateEntity() { }
}

Prior to JAVA-3408 the above code was able to be encoded successfully. Now in 4.0 trying to write the same MongoStateEntity fails with:

Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: An exception occurred when encoding using the AutomaticPojoCodec.
Encoding a MongoStateEntity: 'pojo.MongoStateEntity@37883b97' failed with the following exception:
 
MongoStateEntity contains generic types that have not been specialised.
Top level classes with generic types are not supported by the PojoCodec.
 
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)
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
        at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:200)
        at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:187)
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
        at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
        at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:77)
        at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59)
        at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:145)
...

Prior to JAVA-3408 the typeParameterMap.hasTypeParameters() check would return false for MongoStateEntity. Now it returns true which prevents encoding/decoding this class.

I believe the toString() representation shows why the check now fails.

Prior to 4.0.0:

TypeParameterMap{fieldToClassParamIndexMap={}}

Once the changes were made in JAVA-3408 the map is now represented as:

TypeParameterMap{fieldToClassParamIndexMap={0=Either{left=null, right=TypeParameterMap{fieldToClassParamIndexMap={}}}}}



 Comments   
Comment by John Murphy [ 24/May/21 ]

Reviewing this closer, support for top-level generics has never been supported since the feature was introduced in version 3.5.

From the Java driver 3.5 POJO documentation:

Generics support
Generics are fully supported. During the creation of a ClassModelBuilder type parameters are inspected and saved to work around type erasure. The only requirement is the top level POJO cannot contain any type parameters.
...
This is because the runtime type parameter information is erased by the JVM, and the type parameters cannot be specialized accurately.

Adding complete support for this within the driver does not possible due to the JVM, therefore I will mark this as Working as Designed.
With the note that possible workarounds include switching to a concrete type for the POJO or using a custom Codec.

Comment by Jeffrey Yemin [ 10/May/21 ]

Thanks, John.  We'll look into it and get back to you.  And please share the project.  That could be helpful.

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