You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi. Sorry for the question, I've posted this on StackOverflow first, but it was closed by SO community (and it will be probably further deleted too, so I will just copy my question here, which is also a proposal for change of Spring Boot defaults)
I'am talking about the spring.data.mongodb.uuid-representation property in Spring Boot, which default is still a java-legacy.
The Data Mongo team is going to change this legacy default on their side soon.
The problem is that when you start a new project based on Spring Boot and then your project gets to the point where you already have some environment with the data which you need to maintain, you can suddenly realize that the UUIDs were serialized in a legacy format, which are hard to work with in Mongo Shell and MongoDB Compass.
And nobody has warned you about that legacy format. Neither Spring Boot, nor Spring Data MongoDB docs mention anything about the approach which will be used for UUID serialization (besides the single mention in a list of Spring Boot properties).
You can also realize that if you want to query something manually for debugging purposes, you can't simply write a query by uuid, because in the simplest case of 00000000-0000-0000-0000-000000000001 the value in a document inside of Mongo will be: BinData(3, 'AAAAAAAAAAABAAAAAAAAAA==') and you have to use a sequence of tricks to manually write a primitive query by some uuid field.
You are surprised with such a default behavior of Spring Boot and try to find the motivation for this default setting, but I personally failed to do so.
What I found is that:
\x03 UUID (Old) - This used to be the UUID subtype, but was deprecated in favor of \x04. Drivers and tools for languages with a native UUID type should handle \x03 appropriately.
Make sure your applications don’t suffer from unnecessary portability issues when working with the UUID data type and avoid the legacy Binary0x03 subtype whenever possible. If you can’t migrate your existing deployment to the new Binary0x04 subtype, remember to configure your MongoDB tools to the correct encoding for the legacy Binary0x03 subtype
Note to the last sentence in the quote: the official tool MongoDB Compass can't be configured to easily query for legacy UUIDs
support for STANDARD uuid representation (0x04) exists in Mongo Java driver for a very long time (also since 2014)
in 2019 developers of Mongo driver also forced its client's code to choose the representation if they want to serialize UUID:
This forces applications that encode or decode documents from MongoDB that
contain java.util.UUID values to explicitly specify the UUID representation
that they want to use. Typically, a new application would choose the STANDARD (BSON binary subtype 4) representation, while an existing application
upgrading to the 4.0 driver would choose JAVA_LEGACY
Of course all of that makes you want to switch to the right representation (Standard v4 binary type for UUID), but Java driver won't support both worlds at the same time, so you will need to migrate the data which your system had already saved to a right format of v4 Binary for UUID. It turns out that the migration is not "a couple of lines" in mongosh, because the Mongo shell env does not provide you any tools for that, while the migration task itself is not easy because byte's order in Binary type 3 and Binary type 4 is different.
And there is a Java-based solution snippet from Studio 3T involving manual byte shifting. Since there is a chance for mistake writing the code like this manually, I've also spent quite some time to produce the solution which moves the hard work of bytes shifting to the shoulders of some library (ideally the driver's source code itself). I will leave the Java-solution relying on using MongoDB's org.mongodb:bson, because I am sure it will save someone's else time in the future and not once (full gist is here):
So, based on all of the above, I do not understand why java-legacy is a default choice for spring.data.mongodb.uuid-representation. Recently Spring Boot 3.0 was released and this behavior of mongo starter did not change. This is not something what I would expect (even for compatibility purposes) from a modern framework which which did a lot of breaking changes recently and even requires me to use Java 17 (I totally like and support the Java 17 decision btw).
I tried to understand the motivation behind that java-legacy default value for property spring.data.mongodb.uuid-representation, but failed. To me it looks like the property was added to Spring Boot just because since version 4 the Mongo driver forced its clients to make a choice and Spring Boot just probably made a wrong default choice not thinking about the default value much (just mimicking the pre-4.0 driver's behavior. Which could be a justified decision for a driver to keep legacy format by default for such a long time for compatibility reasons, but even the driver has removed this default already).
So, if there are no serious reasons to stick with legacy, please consider changing the default value of the property from java-legacy to standard. It would be a nice change for 3.0.0 release of Spring Boot, but the release has already happened.
The text was updated successfully, but these errors were encountered:
Whenever possible, Spring Boot aligns its defaults with the defaults of the library that is being auto-configured (in this case, Spring Data MongoDB). This reduces the chance of surprise when users move between auto-configuring and manually configuring the library. If Spring Data MongoDB changes the default, then Spring Boot can react accordingly.
It might be possible for Spring Boot to not have a default at all, but to only apply the spring.data.mongodb.uuid-representation value if it is provided explicitly, This wouldn't help with your problem currently, but it would be the full decision on the default value in Spring Data MongoDB. I'll mark this issue for team attention so others can comment on whether they think we should do this.
If we removed our default, we'd still want to provide additional metadata so that users know what the default from Spring Data will be. As such, I don't think there's that much benefit in removing it. My preference is to leave things as they are until the change lands in Spring Data.
We'd like to add a test to verify that the default value for spring.data.mongodb.uuid-representation matches the default in Spring Data MongoDB. That way when we upgrade to a later version of Spring Data MongoDB that includes the change to the default, we'll have a failing test that triggers Boot to change its default.
wilkinsona
changed the title
Changing the way of storing UUID in MongoDB from legacy to standard in Spring Boot default configuration
Add a test that verifies that the default for spring.data.mongodb.uuid-representation is aligned with Spring Data's default
Jan 19, 2023
Uh oh!
There was an error while loading. Please reload this page.
Hi. Sorry for the question, I've posted this on StackOverflow first, but it was closed by SO community (and it will be probably further deleted too, so I will just copy my question here, which is also a proposal for change of Spring Boot defaults)
I'am talking about the
spring.data.mongodb.uuid-representation
property in Spring Boot, which default is still ajava-legacy
.The Data Mongo team is going to change this legacy default on their side soon.
The problem is that when you start a new project based on Spring Boot and then your project gets to the point where you already have some environment with the data which you need to maintain, you can suddenly realize that the UUIDs were serialized in a legacy format, which are hard to work with in Mongo Shell and MongoDB Compass.
And nobody has warned you about that legacy format. Neither Spring Boot, nor Spring Data MongoDB docs mention anything about the approach which will be used for UUID serialization (besides the single mention in a list of Spring Boot properties).
You can also realize that if you want to query something manually for debugging purposes, you can't simply write a query by uuid, because in the simplest case of
00000000-0000-0000-0000-000000000001
the value in a document inside of Mongo will be:BinData(3, 'AAAAAAAAAAABAAAAAAAAAA==')
and you have to use a sequence of tricks to manually write a primitive query by some uuid field.You are surprised with such a default behavior of Spring Boot and try to find the motivation for this default setting, but I personally failed to do so.
What I found is that:
Note to the last sentence in the quote: the official tool MongoDB Compass can't be configured to easily query for legacy UUIDs
STANDARD
uuid representation (0x04
) exists in Mongo Java driver for a very long time (also since 2014)Of course all of that makes you want to switch to the right representation (Standard v4 binary type for UUID), but Java driver won't support both worlds at the same time, so you will need to migrate the data which your system had already saved to a right format of v4 Binary for UUID. It turns out that the migration is not "a couple of lines" in
mongosh
, because the Mongo shell env does not provide you any tools for that, while the migration task itself is not easy because byte's order in Binary type 3 and Binary type 4 is different.And there is a Java-based solution snippet from Studio 3T involving manual byte shifting. Since there is a chance for mistake writing the code like this manually, I've also spent quite some time to produce the solution which moves the hard work of bytes shifting to the shoulders of some library (ideally the driver's source code itself). I will leave the Java-solution relying on using MongoDB's
org.mongodb:bson
, because I am sure it will save someone's else time in the future and not once (full gist is here):So, based on all of the above, I do not understand why
java-legacy
is a default choice forspring.data.mongodb.uuid-representation
. Recently Spring Boot 3.0 was released and this behavior of mongo starter did not change. This is not something what I would expect (even for compatibility purposes) from a modern framework which which did a lot of breaking changes recently and even requires me to use Java 17 (I totally like and support the Java 17 decision btw).I tried to understand the motivation behind that
java-legacy
default value for propertyspring.data.mongodb.uuid-representation
, but failed. To me it looks like the property was added to Spring Boot just because since version 4 the Mongo driver forced its clients to make a choice and Spring Boot just probably made a wrong default choice not thinking about the default value much (just mimicking the pre-4.0 driver's behavior. Which could be a justified decision for a driver to keep legacy format by default for such a long time for compatibility reasons, but even the driver has removed this default already).So, if there are no serious reasons to stick with legacy, please consider changing the default value of the property from
java-legacy
tostandard
. It would be a nice change for 3.0.0 release of Spring Boot, but the release has already happened.The text was updated successfully, but these errors were encountered: