diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java index b8fd95c1e..92832c471 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java @@ -19,20 +19,26 @@ import lombok.EqualsAndHashCode; import lombok.Value; import lombok.experimental.UtilityClass; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; +import java.io.StringWriter; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.UUID; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.bind.DatatypeConverter; -import org.bson.BSON; +import org.bson.codecs.BinaryCodec; +import org.bson.codecs.Codec; +import org.bson.codecs.UuidCodec; +import org.bson.codecs.configuration.CodecConfigurationException; +import org.bson.codecs.configuration.CodecRegistry; +import org.bson.json.JsonWriter; +import org.bson.types.Binary; import org.springframework.data.mongodb.repository.query.StringBasedMongoQuery.ParameterBinding; import org.springframework.data.repository.query.EvaluationContextProvider; import org.springframework.expression.EvaluationContext; @@ -44,6 +50,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import com.mongodb.DBObject; +import com.mongodb.MongoClient; import com.mongodb.util.JSON; /** @@ -60,6 +67,7 @@ class ExpressionEvaluatingParameterBinder { private final SpelExpressionParser expressionParser; private final EvaluationContextProvider evaluationContextProvider; + private final CodecRegistry codecRegistry; /** * Creates new {@link ExpressionEvaluatingParameterBinder} @@ -75,6 +83,7 @@ class ExpressionEvaluatingParameterBinder { this.expressionParser = expressionParser; this.evaluationContextProvider = evaluationContextProvider; + this.codecRegistry = MongoClient.getDefaultCodecRegistry(); } /** @@ -215,40 +224,41 @@ class ExpressionEvaluatingParameterBinder { if (value instanceof byte[]) { - String base64representation = DatatypeConverter.printBase64Binary((byte[]) value); - - if (!binding.isQuoted()) { - return "{ '$binary' : '" + base64representation + "', '$type' : '" + BSON.B_GENERAL + "'}"; + if (binding.isQuoted()) { + return DatatypeConverter.printBase64Binary((byte[]) value); } - return base64representation; + return encode(new Binary((byte[]) value), BinaryCodec::new); } if (value instanceof UUID) { - UUID uuid = (UUID) value; - if (binding.isQuoted()) { - return uuid.toString(); + return value.toString(); } - String base64representation = DatatypeConverter.printBase64Binary(asBinary(uuid)); - return "{ '$binary' : '" + base64representation + "', '$type' : '" + BSON.B_UUID + "'}"; + return encode((UUID) value, UuidCodec::new); } return JSON.serialize(value); } - private static byte[] asBinary(UUID uuid) { + private String encode(T value, Supplier> defaultCodec) { - byte[] bytes = new byte[16]; + Codec codec; - ByteBuffer bb = ByteBuffer.wrap(bytes) // - .order(ByteOrder.LITTLE_ENDIAN) // - .putLong(uuid.getMostSignificantBits()) // - .putLong(uuid.getLeastSignificantBits()); + try { + codec = codecRegistry.get((Class) value.getClass()); + } catch (CodecConfigurationException exception) { + codec = defaultCodec.get(); + } - return bb.array(); + StringWriter writer = new StringWriter(); + + codec.encode(new JsonWriter(writer), value, null); + writer.flush(); + + return writer.toString(); } /**