The uuidRepresentation has not been specified, so the UUID cannot be encoded

Hi. Couldn’t solve the issue with CodecConfigurationExcpetion throwing :frowning:
The issue is described here org.bson.codecs.configuration.CodecConfigurationException: The uuidRepresentation has not been specified, so the UUID cannot be encoded. · Issue #3546 · spring-projects/spring-data-mongodb · GitHub
It seems like the uuidRepresentation setting is not picked up by the registry.

Driver version 4.1.1.
Spring Mongo Data version 3.1.3
Spring Boot version 2.4.0

Hi there.

I tried the workaround suggested by Christoph and it produced the expected result:

    MongoClientSettings clientSettings = MongoClientSettings.builder().uuidRepresentation(UuidRepresentation.STANDARD).build();
    CodecRegistry codecRegistry = MongoClients.create(clientSettings).getDatabase("test").getCodecRegistry();

    Document document = new Document("id", UUID.randomUUID());

    System.out.println(document.toJson(codecRegistry.get(Document.class)));

The output is:

{"id": {"$binary": {"base64": "Er5BaasHQaaYOdEyv9wphg==", "subType": "04"}}}

Are you seeing something different, or are you looking for a more elegant solution?

Regards,
Jeff

1 Like

Hi, Jeffrey! Thanks for the quick response :slight_smile:
The problem is that I want to customize UuidCodec to not use default UuidRepresentation.UNSPECIFIED value but use UuidRepresentation.STANDARD or UuidRepresentation.JAVA_LEGACY…
I found that the reason is that my application is using Document#toJson method while trying to convert the value to POJO. And this method invocation causes this error :frowning:
If there is a default value for default DocumentCodec() which is used by toJson(jsonWritter) method I would be grateful if there are some ways to customize it.

I’m not sure I understand. The code I included above is the most straightforward way to customize the behavior to use STANDARD UuidRepresentation.

Perhaps if you provide a code sample indicating how you would like it to work, we can go from there.

Regards,
Jeff

Thanks, Jeff. I appreciate this. Your solution is good for me, I will use it in unit tests. Also, I have the next code to aggregate results:

protected <T> List<T> executeAggregation( final Aggregation aggregation, final Class collectionType, final Class<T> clazz ) {

    def collectionName = MongoCollectionUtils.getPreferredCollectionName( collectionType )
    def options = new AggregationOptions( true, false, null )
    def updatedAggregation = aggregation.withOptions( options )
    def results = theMongoOperations.aggregate( updatedAggregation, collectionName, clazz )
    results.mappedResults
}

When I tried to execute aggregation with default grouping like group( USER_ID, KNOWN, LEARNING ).sum( TIME ).as( TIME ) my integration tests is blowing up with the next exception:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [org.bson.Document] to type [java.lang.String] for value ‘Document{{user-id=d340a0eb-647d-4187-9a69-134579ec2539, known=SPANISH, learning=ENGLISH}}’; nested exception is org.bson.codecs.configuration.CodecConfigurationException: The uuidRepresentation has not been specified, so the UUID cannot be encoded.
Caused by: org.bson.codecs.configuration.CodecConfigurationException: The uuidRepresentation has not been specified, so the UUID cannot be encoded.
at org.bson.codecs.UuidCodec.encode(UuidCodec.java:72)
at org.bson.codecs.UuidCodec.encode(UuidCodec.java:37)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:203)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:217)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:159)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:46)
at org.bson.Document.toJson(Document.java:440)
at org.bson.Document.toJson(Document.java:413)
at org.bson.Document.toJson(Document.java:400)
at org.springframework.data.mongodb.core.convert.MongoConverters$DocumentToStringConverter.convert(MongoConverters.java:241)
at org.springframework.data.mongodb.core.convert.MongoConverters$DocumentToStringConverter.convert(MongoConverters.java:234)
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
… 41 more

It seems like when document is trying to be converted from string using the next lines inside:

Codec codec = registry.get(value.getClass());
encoderContext.encodeWithChildContext(codec, writer, value);

The UuidCodec returned with UNSPECIFIED UuidRepresentation value…

Eventually, I found the cause… So the problem is that in Spring Data 3.x when I use group like:

Aggregation.group( FieldOne, FieldTwo, FieldThree )

I will have as result the next aggregation:

Document { _id: Document { [FieldOne: X, FieldTwo: Y, FieldThree: Z] }, FieldOne: X, FieldTwo: Y, FieldThree: Z }

I have CodecConfigurationExcpetion because _id: [FieldOne: X, FieldTwo: Y, FieldThree: Z] can not be cast to UUID…

Composite ids from Aggregation.Group() are no longer mapped to their respective fields. Jeff, could you please provide some info on how to deal with such a case, and is there any way to reverse/configure this?