pogend
pogend
发布于 1周前

Spring Data Mongo插入包含点(.)的key报错:MappingException: Map key user.name contains dots but no replacement was configured!

使用Spring Data Mongo插入带有点符号(.)的键时,抛出MappingException异常。

报错信息如下:

org.springframework.data.mapping.model.MappingException: Map key user.name contains dots but no replacement was configured! Make sure map keys don't contain dots in the first place or configure an appropriate replacement!
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.potentiallyEscapeMapKey(MappingMongoConverter.java:711)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.prepareMapKey(MappingMongoConverter.java:693)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeMapInternal(MappingMongoConverter.java:660)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:387)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:361)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:84)
at org.springframework.data.mongodb.core.CustomMongoTemplate.toDbObject0(CustomMongoTemplate.java:780)
at org.springframework.data.mongodb.core.CustomMongoTemplate.doInsert(CustomMongoTemplate.java:762)
at org.springframework.data.mongodb.core.CustomMongoTemplate.insert(CustomMongoTemplate.java:707)

这个错误在异常信息里也是说明了,是因为mongo的键是不能包含点符号“.“,所以需要在插入包含点符号的键做转换。

在Spring Data Mongo里的MappingMongoConverter转换器提供了setMapKeyDotReplacement的方法,用于我们设置对键中包含点符号(.)做替换。

使用如下:

@Configuration
public class PrimaryMongoConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.data.mongodb")
    public MongoProperties primaryMongoProperties() {
        return new MongoProperties();
    }
    @Primary
    @Bean
    public MongoTemplate primaryMongoTemplate() throws Exception {
        return new MongoTemplate(primaryFactory(), mappingMongoConverter());
    }
    @Bean
    @Primary
    public MongoDbFactory primaryFactory() throws Exception {
        MongoProperties mongoProperties = primaryMongoProperties();
        ServerAddress serverAddress = new ServerAddress(mongoProperties.getHost(), mongoProperties.getPort());
        List<MongoCredential> mongoCredentialList = new ArrayList<>();
        mongoCredentialList.add(MongoCredential.createCredential(mongoProperties.getUsername(),
                mongoProperties.getAuthenticationDatabase(), mongoProperties.getPassword()));
        return new SimpleMongoDbFactory(new MongoClient(serverAddress, mongoCredentialList), mongoProperties.getDatabase());
    }
    @Bean
    public MappingMongoConverter mappingMongoConverter() throws Exception {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(primaryFactory());
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
        converter.setMapKeyDotReplacement("_");
        converter.afterPropertiesSet();
        return converter;
    }
}

在mappingMongoConverter方法里调用了converter.setMapKeyDotReplacement("__"),把“.”转换为“\__”。这样查到Mongo里的包含“.”的键就会使用“__”代替。