Reputation: 91
I am trying to customize the collection name where an entity class is saved into and indexed, using Spring Data MongoDB and Spring Batch. The class is declared as follows:
@Document
@CompoundIndex(name = "unique_source", def = "{'fid': 1, 'sid': 1}", unique = true, background = true)
public class VariantSource {
...
}
And the item writer:
public class VariantSourceMongoWriter extends MongoItemWriter<VariantSource> {
public VariantSourceEntityMongoWriter(MongoOperations mongoOperations, String collectionName) {
setTemplate(mongoOperations);
setCollection(collectionName);
}
}
Saving works fine: the objects are written into the collection provided as argument. The problem is that the indexes are created in the default collection, named after the class name (variantSource
).
After reading this and this, I created the following:
public class MongoCollections {
public String getCollectionFilesName() {
return "my_custom_collection_name"; // TODO Dynamic value
}
}
@Configuration
public class MongoCollectionsConfiguration {
@Bean
public MongoCollections mongoCollections() {
return new MongoCollections();
}
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MongoCollectionsConfiguration.class})
public class VariantSourceMongoWriterTest {
@Autowired
private MongoCollections mongoCollections;
}
I have checked the instance is correctly autowired into the unit tests, but I can't make it work with SpEL.
After changing the @Document
annotation to look like this:
@Document(collection = "#{@mongoCollections.getCollectionFilesName()}")
the following exception is thrown:
org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 1): No bean resolver registered in the context to resolve access to bean 'mongoCollections'
And if I use this:
@Document(collection = "#{mongoCollections.getCollectionFilesName()}")
the exception is this one:
org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'mongoCollections' cannot be found on null
Finally, the following creates a collection with the name as specified, symbols included:
@Document(collection = "@mongoCollections.getCollectionFilesName()")
Upvotes: 9
Views: 4572
Reputation: 552
I was able to get my @Document
tag to access a bean by simply changing my MongoTemplate
configuration file.
Previously, I had it set up like this:
@Configuration
public class MongoTemplateConfiguration {
...
@Bean
public MongoTemplate mongoTemplate() {
...
return new MongoTemplate(...);
}
}
Changing it to follow this (3.2 Java Configuration) format was all I needed in order to remove the "bean resolver" error:
@Configuration
public class MongoTemplateConfiguration extends AbstractMongoClientConfiguration {
...
@Override
@Bean
public com.mongodb.client.MongoClient mongoClient() {
MongoClientSettings settings = ...;
return MongoClients.create(settings);
}
}
Upvotes: 0
Reputation: 369
Make sure that your bean mongoCollections is registered in the application context, and also correct the SpEL expression as below.
@Document(collection = "#{@mongoCollections.getCollectionFilesName()}")
Upvotes: 1
Reputation: 904
As pointed by this answer, to fix the injection:
@Document(collection = "#{mongoCollections.getCollectionFilesName()}")
SpelEvaluationException: EL1007E:(pos 0): Property or field 'mongoCollections' cannot be found on null
(or a direct method bean: @Document(collection = "#{getCollectionFilesName}")
), try setting the ApplicationContext into the MongoMappingContext (which is used to instantiate the MongoConverter, and later the MongoTemplate):
@Bean
public MongoMappingContext MongoMappingContext() {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(applicationContext);
return mappingContext;
}
Upvotes: 5