but in the end I realized that the problem is that AbstractMongoQuery is cached between requests(maybe a problem in my config?), and its query-method object of type MongoQueryMethod, which holds the metadata, MongoEntityMetadata. And thus make this approach (use SpEL in @Document annotation) not fully working.
AbstractMongoQuery deals with different kind of executions. All of them but SingleEntityExecution suffers from this problem, and it's because in SingleEntityExecutionmongoOperations is called without passing collectionName and thus letting, in the end, BasicMongoPersistentEntity.getCollection apply SpEL over entity class to obtain the runtime collection name.
It seems that metadata object of type MongoEntityMetadata that belongs to MongoQueryMethod is updated only once in method getEntityInformation() , because QueryMethod object that holds a reference to this seems to be pooled/cached by infrastructure code makes @Document annotations with Spel useless (once cached never changes)
Default methods like findAll findOne provided out of the box (SimpleMongoRepository) do not have this problem.
From my point of view(and knowledge :) ) there are just three choices,
recreate the metadata ( SimpleMongoEntityMetadata) each time a call to getEntityInformation is done
make object SimpleMongoEntityMetadata which implements interface MongoEntityMetadata mutable, and therefore changing interface signature :|
modify all Execution inner classes defined in AbstractMongoQuery in order to let injected MongoOperations guess the correrct collection name at runtime
Ups ... I forgot , as a workaround I am using MongoOperations in my custom repository xxxImpl, but I think that it would be quite useful for everyone
As the number of @Repository beans in my project increase I've tried to use AOP in order to modify this behaviour, by setting a null collection name in MongoEntityMetadata but this does not help because changes in AbstractMongoQuery inner classes, that implement Execution interface, would also need to be done in order to check if MongoEntityMetadata collection name is null and use a different MongoTemplate method signature.
The point is that MongoTemplate is smart enough to guess the right collection name by using its private method determineEntityCollectionName
I've applied a reduced version of your pull request to master and the bugfix branches. SimpleMongoEntityMetadata now keeps a reference to the MongoPersistentEntity and thus delegates calls to getCollectionName() on each invocation. Feel free to give the snapshot builds a spin