[JAVA-5319] TreeSet Is Properly Encoded but Cannot be Decoded Created: 05/Feb/24  Updated: 05/Feb/24

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

Type: Bug Priority: Minor - P4
Reporter: Ramasai Tadepalli Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Java Drivers
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

TreeSet can be properly encoded into the database but cannot be decoded when being used in a POJO. This is because CollectionPropertyCodecProvider only accounts for HashSet and not for TreeSet.

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

Running with version 4.11.1 against a standalone (but I presume the issue can be reproduced with any cluster topology).

How to Reproduce

public class TreeSetDecodingBugPoc {
  public static void main(String... args) {
    CodecRegistry registry = fromRegistries(
        MongoClientSettings.getDefaultCodecRegistry(),
        fromProviders(PojoCodecProvider.builder().automatic(true).build()));
 
    MongoClient client = MongoClients.create();
    Example example = new Example(new TreeSet<>(List.of("one", "two")));
    client.getDatabase("exampleDb").getCollection("exampleColl", Example.class).withCodecRegistry(registry).insertOne(example);
    Example insertedExample = client.getDatabase("exampleDb").getCollection("exampleColl", Example.class).withCodecRegistry(registry).find().first();
    System.out.println(insertedExample.getExample());
  }
 
  public static class Example {
    @BsonProperty("example")
    public SortedSet<String> example = new TreeSet<>();
 
    @BsonCreator
    public Example(@BsonProperty("example") TreeSet<String> example) {
      this.example = example;
    }
 
    @BsonProperty("example")
    public SortedSet<String> getExample() {
      return this.example;
    }
 
    @BsonProperty("example")
    public void setExample(SortedSet<String> example) {
      this.example = example;
    }
  }
} 

The document is stored in the DB properly (queried using mongosh):

{
  _id: ObjectId('65c05203c9d2486e182f3e65'),
  example: [ 'one', 'two' ]
} 

Querying for it will yield the exception:

Caused by: org.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'Example'. Decoding 'example' errored with: Unsupported Collection interface of java.util.SortedSet! 



 Comments   
Comment by Jeffrey Yemin [ 05/Feb/24 ]

Thanks for the report, ramasai.tadepalli@mongodb.com. As a workaround, both of these are supported:

    // record support is more robust 
    public record ExampleRecord(SortedSet<String> example) {
    }
 
    // A regular Set works ok too
    public static class Example {
        @BsonProperty("example")
        public Set<String> example;
 
        @BsonCreator
        public Example(@BsonProperty("example") Set<String> example) {
            this.example = example;
        }
 
        @BsonProperty("example")
        public Set<String> getExample() {
            return this.example;
        }
    }

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