【问题标题】:Spring Data Entity UUID is stored as legacy UUID in MongoDBSpring Data Entity UUID 在 MongoDB 中存储为 legacy UUID
【发布时间】:2020-02-21 16:27:56
【问题描述】:

我正在将一些数据转储到我的 MongoDb 并在途中生成一个 UUID。在集合中,此 UUID 字段存储为 LUUID(传统 UUID - 类型 3),我不知道如何避免这种情况,因为我希望格式为标准 UUID(类型 4)。

实体:

@Document(collection = "sms")
public class SmsEntity {
    ...
    private UUID ubmMessageSid;  // <- this field gets stored as LUUID
    ...

    public static class Builder {
    ...
        private UUID ubmMessageSid;
    ...

        public Builder ubmMessageSid(UUID ubmMessageSid) {
            this.ubmMessageSid = ubmMessageSid;
            return this;
        }

        public SmsEntity build() {return new SmsEntity(this);}
    }
}

回购:

@Repository
public interface SmsRepository extends CrudRepository<SmsEntity, String> {
}

存储此实体的服务:

...
var ubmId = UUID.randomUUID();
var smsEntity = SmsEntity.builder()
    .ubmMessageSid(ubmId)
    ...
    .build();
repository.save(smsEntity);

我必须注释或配置以将 UUID 存储为 Binary/type4 的任何内容?

【问题讨论】:

    标签: mongodb spring-boot spring-data uuid


    【解决方案1】:

    就我而言,application.yml 中的属性不如使用 CodecRegistries 的属性好用。我的工作解决方案是:

    MongoConfig.java:

        @Bean
        public MongoClient mongoClient() {
            MongoClientSettings.Builder builder = MongoClientSettings.builder();
            builder.uuidRepresentation(UuidRepresentation.JAVA_LEGACY);
            return MongoClients.create(builder.build());
        }
    

    【讨论】:

      【解决方案2】:

      在 Spring Boot 2 中,对于 Spring MongoDB 3.x,您可以使用自动配置属性进行设置:

      # Options: unspecified, standard, c_sharp_legacy, java_legacy, python_legacy
      spring.data.mongodb.uuid-representation=standard
      

      【讨论】:

        【解决方案3】:

        在 Spring Data Mongo 的 3.x 版本上,MongoClient 已被 MongoClientSettings 取代:

        CodecRegistry codecRegistry =
          CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new UuidCodec(UuidRepresentation.JAVA_LEGACY)),
            MongoClientSettings.getDefaultCodecRegistry());
        
        return new MongoClient(new ServerAddress(address, port), MongoClientSettings.builder().codecRegistry(codecRegistry).build());
        

        【讨论】:

        • 我不认为你可以return new MongoClient(...),而是你需要return MongoClients.create(...);more info here
        【解决方案4】:

        您可以在 Mongo 配置中设置 UUID 编解码器。这将使用 4 类编解码器保留您的 UUID。您需要执行的代码如下:

        CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)),
                                MongoClient.getDefaultCodecRegistry());
                return new MongoClient(new ServerAddress(address, port), MongoClientOptions.builder().codecRegistry(codecRegistry).build());
        

        这是完整的课程以防万一:

        import com.mongodb.MongoClient;
        import com.mongodb.MongoClientOptions;
        import com.mongodb.ServerAddress;
        import org.bson.UuidRepresentation;
        import org.bson.codecs.UuidCodec;
        import org.bson.codecs.configuration.CodecRegistries;
        import org.bson.codecs.configuration.CodecRegistry;
        import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
        import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
        import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
        import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
        
        @Configuration
        @EnableAutoConfiguration
        @EnableMongoRepositories(basePackages = "com.yourpackage.repositories")
        public class MongoConfig extends AbstractMongoConfiguration {
            @Value("${mongo.database}")
            String database;
            @Value("${mongo.address}")
            String address;
            @Value("${mongo.port}")
            Integer port;
        
            @Override
            protected String getDatabaseName() {
                return database;
            }
        
            @Override
            public MongoClient mongoClient() {
                CodecRegistry codecRegistry =
                        CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)),
                                MongoClient.getDefaultCodecRegistry());
                return new MongoClient(new ServerAddress(address, port), MongoClientOptions.builder().codecRegistry(codecRegistry).build());
            }
        
            @Bean
            public LocalValidatorFactoryBean localValidatorFactoryBean() {
                return new LocalValidatorFactoryBean();
            }
        
            @Bean
            public ValidatingMongoEventListener validatingMongoEventListener() {
                return new ValidatingMongoEventListener(localValidatorFactoryBean());
            }
        }
        

        注意:随着新的 Spring Boot 版本 2.2.0.RELEASE AbstractMongoConfiguration 被弃用,这不再有效。我为此发了一个帖子,也许这是一个错误或者也许有人知道答案:Spring Boot Standard UUID codec not working with AbstractMongoClientConfiguration

        【讨论】:

          猜你喜欢
          • 2018-09-26
          • 1970-01-01
          • 1970-01-01
          • 2017-07-06
          • 2017-08-20
          • 2014-09-13
          • 2017-11-28
          • 1970-01-01
          • 2021-02-03
          相关资源
          最近更新 更多