[JAVA-2720]  Support Enums in query helpers Created: 29/Dec/17  Updated: 05/Apr/22  Resolved: 05/Apr/22

Status: Closed
Project: Java Driver
Component/s: Codecs, POJO
Affects Version/s: 3.6.0
Fix Version/s: None

Type: New Feature Priority: Major - P3
Reporter: Cezary Bartosiak Assignee: Unassigned
Resolution: Duplicate Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates JAVA-4440 Add codec and codec provider for enum... Closed
Related
related to JAVA-4429 Updates push/addToSet Does Not Add Di... Closed
is related to JAVA-4440 Add codec and codec provider for enum... Closed
Case:

 Description   

Hi,

Let's assume we have the following POJO:

public final class Person {
 
    private final String  name;
    private final Country country;
 
    @BsonCreator
    public Person(
            @BsonProperty("name") String name,
            @BsonProperty("country") Country country) {
 
        this.name = name;
        this.country = country;
    }
 
    @BsonId
    public String getName() {
        return name;
    }
 
    public Country getCountry() {
        return country;
    }
 
    public enum Country {
        IRELAND,
        POLAND
    }
}

Now we create a related collection:

MongoCollection<Person> collection = new MongoClient()
        .getDatabase("database")
        .getCollection("people", Person.class)
        .withCodecRegistry(fromRegistries(
                getDefaultCodecRegistry(),
                fromProviders(
                        PojoCodecProvider
                                .builder()
                                .automatic(true) // note the automatic POJO support
                                .build()
                )
        ));

Everything is fine when you do simple CRUD operations. But try to do the following:

Person person = collection
        .find(eq("country", POLAND))
        .first();

You will get org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.gat.lib.mongo.Person$Country

In such cases you need to register an enum codec manually. I think it's confusing, especially as the documentation says that "enums are fully supported" while they are limited to simple CRUD.



 Comments   
Comment by Jeffrey Yemin [ 05/Apr/22 ]

As the description of this issue was really about supporting Enum values in queries, I changed the title to reflect that, and am closing as a duplicate of JAVA-4440.

Comment by Javier Alfonso Bellota de Frutos [ 26/Feb/20 ]

Hello,

Which status is this at? By @Aarjav comment, it seems that its PR could be ok to be merged but the comment was about a year ago.

I don't know how this is implemented but if having custom codecs is a problem, it would be a problem also with Map (that I think is supported), wouldn't it?

 

Comment by Aarjav Patel [ 26/Feb/19 ]

Thanks for the quick review.

I did think about what would happen if there were already custom codecs for the enums available when I was making the code change. I initially thought that in the PojoCodecProvider class I would be able to query the CodecRegistry that gets passed to the get method, however when I did, I just got a StackOverflowException. Then I realized that if the custom codec for enum already exists for the enum, it will be used before it gets to the PojoCodecProvider (as you've mentioned in the github PR) since it is recommended that PojoCodecProvider be the 'last' provider in the CodecRegistry.

Are there any tests I could add to test for compatibility with existing working code which is affected by this change? I agree we cannot guarantee enum will be stored as its name, and need to make sure we do not break existing behavior. Is there anything else I can do for resolving this issue?

Thanks again,

  • Aarjav
Comment by Ross Lawley [ 26/Feb/19 ]

Hi aarjav,

Thanks for the PR - there maybe some issues that need further consideration like having custom codecs for Enums when used with POJO's. We cannot guarantee that it will always be stored as the string value.

That said as a low level codec your EnumCodec approach works for your usecase. So in the meantime please configure your MongoClient / MongoDatabase / MongoCollection to use it alongside the with the default codec registry.

Ross

Comment by Aarjav Patel [ 25/Feb/19 ]

I have made a pull request for this: https://github.com/mongodb/mongo-java-driver/pull/503 I am not sure how to get it to automatically link here.

@ross.lawley can you review this when you get the chance?

Comment by Cezary Bartosiak [ 29/Dec/17 ]

Of course this is a limitation of the automatic POJO support only.

Generated at Thu Feb 08 08:57:55 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.