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

时间:2022-06-01 21:57:53

使用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里的包含“.”的键就会使用“__”代替。