Reputation: 1015
I am using Spring Data for MongoDB and I need to be able to configure collection at runtime.
My repository is defined as:
@Repository
public interface EventDataRepository extends MongoRepository<EventData, String> {
}
I tried this silly example:
@Document(collection = "${mongo.event.collection}")
public class EventData implements Serializable {
but mongo.event.collection did not resolve to a name as it does with a @Value annotation.
A bit more debugging and searching and I tried the following: @Document(collection = "#{${mongo.event.collection}}")
This produced an exception:
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E:(pos 1): After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:129)
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:60)
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:32)
at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpressions(TemplateAwareExpressionParser.java:154)
at org.springframework.expression.common.TemplateAwareExpressionParser.parseTemplate(TemplateAwareExpressionParser.java:85)
Perhaps I just don't know how to quite use SPel to access values from Spring's Property Configurer.
When stepping through the code, I see that there is a way to specify collection name or even expressions, however, I am not sure which annotation should be used for this purpose or how to do it.
Thanks. -AP_
Upvotes: 7
Views: 17003
Reputation: 103
You can solve this problem by just using SPeL:
@Document(collection = "#{environment.getProperty('mongo.event.collection')}")
public class EventData implements Serializable {
...
}
Update Spring 5.x:
Since Spring 5.x or so you need an additional @ before environment:
@Document(collection = "#{@environment.getProperty('mongo.event.collection')}")
public class EventData implements Serializable {
...
}
Docs:
Upvotes: 6
Reputation: 31
define your entity class like
@Document(collection = "${EventDataRepository.getCollectionName()}")
public class EventData implements Serializable {
Define a custom repository interface with getter and setter methods for "collectionName"
public interface EventDataRepositoryCustom {
String getCollectionName();
void setCollectionName(String collectionName);
}
provide implementation class for custom repository with "collectionName" implementation
public class EventDataRepositoryImpl implements EventDataRepositoryCustom{
private static String collectionName = "myCollection";
@Override
public String getCollectionName() {
return collectionName;
}
@Override
public void setCollectionName(String collectionName) {
this.collectionName = collectionName;
}
}
Add EventDataRepositoryImpl
to the extends list of your repository interface in this it would look like
@Repository
public interface EventDataRepository extends MongoRepository<EventData, String>, EventDataRepositoryImpl {
}
Now in your Service class where you are using the MongoRepository
set the collection name, it would look like
@Autowired
EventDataRepository repository ;
repository.setCollectionName("collectionName");
Upvotes: 3
Reputation: 1
Entity Class
@Document // remove the parameters from here
public class EscalationCase
{
}
Configuration class
public class MongoDBConfiguration {
private final Logger logger = LoggerFactory.getLogger(MongoDBConfiguration.class);
@Value("${sfdc.mongodb.collection}") //taking collection name from properties file
private String collectionName;
@Bean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context) {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory), context);
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
if (!mongoTemplate.collectionExists(collectionName)) {
mongoTemplate.createCollection(collectionName); // adding the collection name here
}
return mongoTemplate;
}
}
Upvotes: 0
Reputation: 1015
So, at the end, here is a work around that did the trick. I guess I really don't know how to access data from Spring Properties Configurer using the SPeL expressions.
In my @Configuration class:
@Value("${mongo.event.collection}")
private String
mongoEventCollectionName;
@Bean
public String mongoEventCollectionName() {
return
mongoEventCollectionName;
}
On my Document:
@Document(collection = "#{mongoEventCollectionName}")
This, appears to work and properly pick up the name configured in my .properties file, however, I am still not sure why I could not just access the value with $ as I do in the @Value annotation.
Upvotes: 5