Reputation: 81
Dear Stack Overflow Community,
I am currently working on a Spring Boot project where the variable names are written in camel case. I also have a MongoDB database with fields written in snake case. Currently I am using @Field annotation provided by Spring Mongo Data to map each variable to its corresponding logical name like this:
@Field("var_name")
private String varName;
My question is - Is there a way to configure globally an automatic Camel Case to Snake Case conversion in Spring Mongo Data? If I have a model with many instance variables, it would be trivial to add a @Field annotation for each of them.
Thank you in advance.
Upvotes: 3
Views: 3163
Reputation: 802
There are 2 ways to do this at global level:
public class MongoConfig extends AbstractReactiveMongoConfiguration {
@Override
public MongoClient reactiveMongoClient() {
return MongoClients.create(uri);
}
@Bean
@Override
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions) throws ClassNotFoundException {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(this.getInitialEntitySet());
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
mappingContext.setFieldNamingStrategy(new SnakeCaseFieldNamingStrategy()); //NOTE this line
mappingContext.setAutoIndexCreation(this.autoIndexCreation());
return mappingContext;
}
Here we override the mappingContext and pass snakeCasing, default for which is camel.
public MongoClient reactiveMongoClient() {
return MongoClients.create(
MongoClientSettings.builder().applyConnectionString(new ConnectionString(uri))
.codecRegistry(codecRegistry())
.build());
}
public CodecRegistry codecRegistry() {
List<Convention> conventions = Collections.<Convention>singletonList(
classModelBuilder -> {
for (PropertyModelBuilder<?> fieldModelBuilder : classModelBuilder.getPropertyModelBuilders()) {
fieldModelBuilder.discriminatorEnabled(false);
fieldModelBuilder.readName(
fieldModelBuilder.getName()
.replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
fieldModelBuilder.writeName(
fieldModelBuilder.getName()
.replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
}
classModelBuilder.enableDiscriminator(true);
classModelBuilder.discriminatorKey("_cls");
classModelBuilder.discriminator(classModelBuilder.getType().getSimpleName()
.replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
});
CodecProvider pojoCodecProvider =
PojoCodecProvider.builder().conventions(conventions).build();
return fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
}
The 2nd one is taken from the test mentioned here, and better explanation is here in the docs
Though I couldnt get 2nd one working but as per this comment it should ideally.
Upvotes: 1
Reputation: 59
For Spring Boot, you can add "field-naming-strategy" into your application.yml like this:
spring:
data:
mongodb:
host: localhost
port: 27017
username: xxxxx
password: yyyyy
authentication-database: admin
database: my_mongo_db
field-naming-strategy: org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy
Upvotes: 3
Reputation: 1
Have you tried mappingContext.setFieldNamingStrategy(new SnakeCaseFieldNamingStrategy()) in your Mongo configuration class?
Upvotes: 0