From 597d6825f70e65011556a4242762610e4ece8777 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 8 Feb 2021 15:47:38 +0100 Subject: [PATCH] Use UUID toString representation when converting org.bson.Document into a json String. This commit switches the rendering of UUID values to their toString format when printing org.bson.Document to json via the DocumentToString converter. This will move the resulting representation from {"$binary": "QUK3ZihZ9cdhWjTf5TZqrw==", "$type": "03"} to 480971b0-7160-4120-acd0-6fd6b82418ad which is the more natural variant within Java applications. The conversion only applies on read in cases where an entire document eg. a composite id, is mapped to a String property of the domain model. Closes #3546. Original pull request: #3551. --- .../mongodb/core/convert/MongoConverters.java | 28 +++++++++++++++---- .../convert/MongoConvertersUnitTests.java | 11 +++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java index 70f8fa732..1ab8bb627 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java @@ -27,14 +27,18 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Currency; import java.util.List; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import org.bson.BsonReader; import org.bson.BsonTimestamp; +import org.bson.BsonWriter; import org.bson.Document; -import org.bson.UuidRepresentation; import org.bson.codecs.Codec; -import org.bson.internal.CodecRegistryHelper; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.codecs.configuration.CodecRegistries; import org.bson.types.Binary; import org.bson.types.Code; import org.bson.types.Decimal128; @@ -240,9 +244,23 @@ abstract class MongoConverters { INSTANCE; - private final Codec codec = CodecRegistryHelper - .createRegistry(MongoClientSettings.getDefaultCodecRegistry(), UuidRepresentation.JAVA_LEGACY) - .get(Document.class); + private final Codec codec = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new Codec() { + + @Override + public void encode(BsonWriter writer, UUID value, EncoderContext encoderContext) { + writer.writeString(value.toString()); + } + + @Override + public Class getEncoderClass() { + return UUID.class; + } + + @Override + public UUID decode(BsonReader reader, DecoderContext decoderContext) { + throw new IllegalStateException("decode not supported"); + } + }), MongoClientSettings.getDefaultCodecRegistry()).get(Document.class); @Override public String convert(Document source) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java index 7e9c7323f..88cf3314d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoConvertersUnitTests.java @@ -22,6 +22,7 @@ import java.net.URI; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Currency; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -29,7 +30,6 @@ import org.assertj.core.data.TemporalUnitLessThanOffset; import org.bson.BsonTimestamp; import org.bson.Document; import org.junit.jupiter.api.Test; - import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.geo.Box; @@ -42,6 +42,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.AtomicLongT import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.BsonTimestampToInstantConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.CurrencyToStringConverter; +import org.springframework.data.mongodb.core.convert.MongoConverters.DocumentToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.IntegerToAtomicIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.LongToAtomicLongConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter; @@ -173,4 +174,12 @@ public class MongoConvertersUnitTests { assertThat(conversionService.convert(URI.create("/segment"), String.class)).isEqualTo("/segment"); assertThat(conversionService.convert("/segment", URI.class)).isEqualTo(URI.create("/segment")); } + + @Test // GH-3546 + void convertsDocumentWithUUidToString() { + + UUID uuid = UUID.randomUUID(); + assertThat(DocumentToStringConverter.INSTANCE.convert(new Document("_id", uuid))) + .isEqualTo("{\"_id\": \"" + uuid.toString() + "\"}"); + } }