spring-data-mongodb
spring-data-mongodb copied to clipboard
Support dynamic naming strategy for collection names [DATAMONGO-1863]
Dan Markhasin opened DATAMONGO-1863 and commented
As described in DATAMONGO-525 (https://jira.spring.io/browse/DATAMONGO-525), we are looking for a way to generate collection names dynamically to support multi-tenancy. This can be achieved by something as simple as a prefix or by a naming strategy mechanism, simliar to FieldNamingStrategy.
For example, the most simple solution that would work (for us) is to have something like this:
@Document(prefix = "${info.service_name}")
class Dog
{
private String breed;
}
That would generate a collection called animalService_Dog (assuming the service name is animalService). Any other solution is welcome, but I believe this is a major feature that is currently lacking which is critical for multi-tenancy support
Reference URL: https://jira.spring.io/browse/DATAMONGO-525
1 votes, 3 watchers
Oliver Drotbohm commented
The collection attribute of @Document already supports SpEl expressions. Does that already do what you want?
Dan Markhasin commented
I believe it does not - as per the example given in DATAMONGO-525, this needs to be dynamic with the ability to extract data from the annotated class itself. If there is any way to achieve my example (only provide a prefix and let BasicMongoPersistentEntity decide what the name of the collection should be given that prefix and the name of the annotated class), that would be great, but looking at the code I currently don't see any way of doing that. What I want to avoid is having to explicitly set the collection name on every class in my application, which is what I currently have to do, i.e.:
@Document(collection= "${info.service_name}_dog")
class Dog
{
private String breed;
}
@Document(collection= "${info.service_name}_cat")
class Cat
{
private String breed;
}
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Does that already do what you want?
No, we need a way to specify in @Document annotation the collection name as property from properties file
https://www.examplefiles.net/cs/1040155
This link specifies how we can use dynamic collection names with the environment variables. It worked for me
I am trying to do something like this, too. My use case entails a configuration that specifies a list of mongo urls, and/or a list of collections for the same URL. If, in my application, I want to perform a kind of query federation over some configured number of collections in one or more mongo instances, I need a way to set up the collection name in the repositories that I configure, especially if they use the same model class, and I don't want to mandate the exact name of the collection. Please let me know if that explanation doesn't make sense, and I will do my best to clear it up.
I can get halfway there, and I'll explain what that means. If I disable mongo repository auto-configuration, and create the repository myself, I can construct a MongoEntityInformation object, and pass the collection name as a constructor parameter. In a custom repo impl, I extend SimpleMongoRepository, and pass this (along with the mongo template) into the constructor. If I use methods from the SimpleMongoRepository base class, then it uses the collection name that is set in the MongoEntityInfo instance. But, if I have methods in the original interface (the one that you include the custom interface in the list of "implements") then it only uses the collection name derived from the model class (either the lower-camel-case version of the name, or whatever is in the @Document(collection = "<some-name-here>") annotation.
I have an example here that demonstrates what I mean. The test writes to embedded mongo, and you have to look in the log output to see the collection name. I don't have a test that checks for the collection that is used when interface methods are invoked, but I can add that soon. So, I think it may be a bug that SimpleMongoRepository obtains the collection name differently than repository interface methods. It is not a problem when there is no custom implementation. However, when there is a custom implementation, or when a developer forgoes auto-configuration for manual configuration in order to get more flexibility in a certain situation, then we get inconsistent behavior.
Does that already do what you want?
No, we need a way to specify in
@Documentannotation the collection name as property from properties file
This feature has already worked for quite a while. if you put @Document(collection = "#{@nameOfBeanHoldingSomeString}" on your model class, it will use the string value of a bean of that name as the collection name. In a configuration class, you read in some property, and expose it as a named bean. And that's it. My case, mentioned above, is a bit more complicated.
Related to: spring-projects/spring-data-commons#2369.