Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Configure MongoDb Collection Name For a Class in Spring Data

I have a collection called Products in my MongoDB database, which is represented by the interface IProductPrice in my Java code. The following repository declaration causes Spring Date to look to the collection db.collection: Intelliprice.iProductPrice.

I want it to configure it to look in db.collection: Intelliprice.Products using an external configuration rather than putting an @Collection(..) annotation on IProductPrice. Is this possible? How can I do this?

public interface ProductsRepository extends     MongoRepository<IProductPrice, String> { } 
like image 304
Danish Avatar asked Sep 05 '12 03:09

Danish


People also ask

How do I set collection name in MongoDB?

The only way you can currently achieve this is by annotating your domain class with @Document using the collection property to define the name of the collection instances of this class shall be persisted to.

How are MongoDB collections named?

The general conventions are: Lowercase names: this avoids case sensitivity issues, as MongoDB collection names are case sensitive. Plural: more obvious to label a collection of something as the plural, e.g. "files" rather than "file"

Which Annotation used on domain class is spring data MongoDB?

The @Id annotation tells the mapper which property you want to use for the MongoDB _id property and the @Indexed annotation tells the mapping framework to call ensureIndex on that property of your document, making searches faster.

Which is better MongoTemplate or MongoRepository?

So I'd say that MongoTemplate is a better option, unless you have a very elaborated POJO model or need the custom queries capabilities of MongoRepository for some reason. Good points/examples. However your race condition example and undesired result can be avoided using @Version to prevent that very scenario.


2 Answers

The only way you can currently achieve this is by annotating your domain class with @Document using the collection property to define the name of the collection instances of this class shall be persisted to.

However, there's a JIRA issue open that suggests adding a pluggable naming strategy to configure the ways class, collection and property names are handled in a more global way. Feel free to comment your use case and vote it up.

like image 52
Oliver Drotbohm Avatar answered Sep 17 '22 20:09

Oliver Drotbohm


using answer from Oliver Gierke above, working on a project where I need to create multiple collections for one entity, I wanted to use the spring repositories and needed to specify the entity to use before using the repository.

I managed to modify the repository collection name on demand using this system, it using SPeL. You can only work on 1 collection at a time though.

Domain object

@Document(collection = "#{personRepository.getCollectionName()}") public class Person{} 

Default Spring Repository:

public interface PersonRepository       extends MongoRepository<Person, String>, PersonRepositoryCustom{ } 

Custom Repository Interface:

public interface PersonRepositoryCustom {     String getCollectionName();      void setCollectionName(String collectionName); } 

implementation:

public class PersonRepositoryImpl implements PersonRepositoryCustom {      private static String collectionName = "Person";      @Override     public String getCollectionName() {         return collectionName;     }      @Override     public void setCollectionName(String collectionName) {         this.collectionName = collectionName;     } } 

To use it:

@Autowired PersonRepository personRepository;  public void testRetrievePeopleFrom2SeparateCollectionsWithSpringRepo(){         List<Person> people = new ArrayList<>();         personRepository.setCollectionName("collectionA");         people.addAll(personRepository.findAll());         personDocumentRepository.setCollectionName("collectionB");         people.addAll(personRepository.findAll());         Assert.assertEquals(4, people.size()); } 

Otherwise if you need to use configuration variables, you could maybe use something like this? source

@Value("#{systemProperties['pop3.port'] ?: 25}")  
like image 29
Jeremie Avatar answered Sep 21 '22 20:09

Jeremie