Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpEL Expressions in @Document annotations are not re-evaluated for query executions [DATAMONGO-1043] #1965

Closed
spring-projects-issues opened this issue Sep 1, 2014 · 4 comments

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Sep 1, 2014

Jordi Llach Fernandez opened DATAMONGO-1043 and commented

Based on the idea of Oliver Gierke in https://jira.spring.io/browse/DATAMONGO-525 I followed some post like the ones below

http://stackoverflow.com/questions/18129291/mongodb-and-spel-expressions-in-document-annotations
and
http://stackoverflow.com/questions/19807733/mongodb-multi-tenacy-spel-with-document?rq=1

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 SingleEntityExecution mongoOperations is called without passing collectionName and thus letting, in the end, BasicMongoPersistentEntity.getCollection apply SpEL over entity class to obtain the runtime collection name.


Affects: 1.5.2 (Dijkstra SR2)

Reference URL: https://jira.spring.io/browse/DATAMONGO-525

Issue Links:

  • DATAMONGO-1320 Support dynamic collection with property
    ("is duplicated by")

Referenced from: pull request #238, and commits 8483f36, cbbafce, b5f7444

Backported to: 1.6.2 (Evans SR2), 1.5.5 (Dijkstra SR5)

1 votes, 4 watchers

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 1, 2014

Jordi Llach Fernandez commented

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,

  1. recreate the metadata ( SimpleMongoEntityMetadata) each time a call to getEntityInformation is done
  2. make object SimpleMongoEntityMetadata which implements interface MongoEntityMetadata mutable, and therefore changing interface signature :|
  3. 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

Thanks in advance

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Sep 3, 2014

Jordi Llach Fernandez commented

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

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Nov 6, 2014

Jordi Llach Fernandez commented

As by Spring4.1.x SpEL compiler as improved its performance (http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/expressions.html#expressions-compiler-configuration) I think that it could be a plausible solution to create a SimpleMongoEntityMetadata by using the MongoPersistentEntity, and not its collectionName.

I have also made a PR to let you check my idea #238

Maybe StandardEvaluationContext should be reviewed when creating SpelExpressionParser in order to use this configuration enhancement available in 4.1.x

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Nov 28, 2014

Oliver Drotbohm commented

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants