spring

Spring Data MongoDB Example

In this example, we will demonstrate how to connect Spring Data with MongoDb. MongoDb is also a document based NoSql Database like Solr, which we demonstrated past week.

Spring Data MongoDb is the module of Spring Data that provides support for MongoDb. As with the other modules demonstrated in this series, this module too provides supports both for derived queries(based on the method name) and the annotated query.
 
 
 
 
 

 
Let´s get started with the setup:

1. How to configure and manage a MongoDb using Spring Data

Install Mongodb depending upon your system from here.

Point to the bin of the installed MongoDb, which is Program Files in Windows. Then run the following command:

mongo --dbpath C:\MongoDb\Data

This command starts the MongoDb Server with the repository location at the path specified in the command above. However, the folders should already be present otherwise the server will throw Invalid Directory error. The default port for MongoDb is 271017.

Now that the Mongo server is up and running, we will setup the application environment.

Create a simple Maven Project in eclipse IDE. We are using the below pom.xml to manage the dependencies for MongoDb from Spring data.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>SpringDataMongoDbExample</groupId>
  <artifactId>SpringDataMongoDbExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.7.2.RELEASE</version>
    </dependency>
</dependencies>
  
</project>

Eclipse will download the required JAR files and add the dependencies in the project classpath. Now that the project is setup and dependencies imported, we can begin writing the actual code.

We start by creating the entities that will be persisted to the Mongo Database.

Person.java

package com.jcg.examples.entity;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="person")
public class Person
{

		@Id
		private Long personId;
		
		private String name;
		
		private int age;
		
		@DBRef(db="address")
		private List<Address> addresses = new ArrayList<>();
		
		public Person()
		{}
		
		
		@PersistenceConstructor
		public Person(Long personId, String name, int age)
		{
				super();
				this.personId = personId;
				this.name = name;
				this.age = age;
		}

		public Long getPersonId()
		{
				return personId;
		}

		public void setPersonId(Long personId)
		{
				this.personId = personId;
		}

		public String getName()
		{
				return name;
		}

		public void setName(String name)
		{
				this.name = name;
		}

		public int getAge()
		{
				return age;
		}

		public void setAge(int age)
		{
				this.age = age;
		}

		public List<Address> getAddresses()
		{
				return addresses;
		}


		public void setAddresses(List<Address> addresses)
		{
				this.addresses = addresses;
		}


		@Override
		public String toString()
		{
				return "Person [personId=" + personId + ", name=" + name + ", age=" + age + ", addresses=" + addresses + "]";
		}
		
}

@Document is used to denote the collection in which the data will be persisted. If it is not mentioned, the data is saved in the collection which has the same name as the Entity Class Name.

@Id maps the property annotated with it to the _id column of the collection. In case no property is annotated with @Id, the property with the name id will be mapped to the _id. In case there is now property with that name, a column will be generated by the Mongo Driver, but the value will not available in the PoJo.

@DBRef is used to relate an existing entity to the current entity. However, unlike the case with Relational Databases, if we save the host entity it does not save the related entity. It has to be persisted separately.

@PersistenceConstructor is used to mark the constructor which is to be used for creating entities when fetching data from the Mongo Server.

Here is the linked entity Address.

Address.java

package com.jcg.examples.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="address")
public class Address
{
		
		@Id
		private long addressId;
		
		private String address;
		
		private String city;
		
		private String state;
		
		private long zipcode;
		
		public Address()
		{
				
				System.out.println("CAlling default cons");
		}

		@PersistenceConstructor
		public Address(long addressId, String address, String city, String state, long zipcode)
		{
				super();
				this.addressId = addressId;
				this.address = address;
				this.city = city;
				this.state = state;
				this.zipcode = zipcode;
		}




		public String getAddress()
		{
				return address;
		}

		public void setAddress(String address)
		{
				this.address = address;
		}

		public String getCity()
		{
				return city;
		}

		public void setCity(String city)
		{
				this.city = city;
		}

		public String getState()
		{
				return state;
		}

		public void setState(String state)
		{
				this.state = state;
		}

		public long getZipcode()
		{
				return zipcode;
		}

		public void setZipcode(long zipcode)
		{
				this.zipcode = zipcode;
		}

		@Override
		public String toString()
		{
				return "Address [address=" + address + ", city=" + city + ", state=" + state + ", zipcode=" + zipcode + "]";
		}		
		
}

Now we will create a Repository for each of the entity defined above which will help us in persisting the respective Entities to the MongoDb Server.

PersonRepo.java

package com.jcg.examples.repo;

import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.CrudRepository;

import com.jcg.examples.entity.Person;

public interface PersonRepo extends CrudRepository<Person, Long>
{
		@Query("{'name' : ?0}")
		public Iterable<Person> searchByName(String personName);

}

Spring Data Module provides us with a number of inbuilt method for manipulating the Data. We need not write the queries for basic data manipulation and reading. It is achieved by extending the CrudRepository interface and declaring the proper Generics as per the Entity, which in our case is the <Person, Long>.

For executing custom written queries, the developer can create his own method by specifying the Query using the @Query annotation. In the above class, we have annotated the method, searchByName with the said annotation. This method returns the Person Entity by querying the name field of the Person Collection from the Server.

Here’s the AddressRepo

AddressRepo.java

package com.jcg.examples.repo;

import org.springframework.data.repository.CrudRepository;

import com.jcg.examples.entity.Address;

public interface AddressRepo extends CrudRepository

The last and the most important part is to configure the Spring Container using the spring-config.xml:

Spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mongo="http://www.springframework.org/schema/data/mongo"
          xsi:schemaLocation=
          "http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- Configure the Mongo Server -->
    <mongo:mongo id="mongo" host="localhost" port="27017"/>
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongo"/>
    <constructor-arg name="databaseName" value="jcg"/>
  </bean>
    
    <mongo:repositories base-package="com.jcg.examples.repo"></mongo:repositories>
    
        
</beans>
  • Line 15: Configure the Mongo Server by providing the server and the Port on which it is running.
  • Line 17: The mongoTemplate is used as a dependency for creating the repositories which we discussed above.
  • Line 22: Scan the packages for initializing Mongo Bean Repositories.

Now that all is set, let’s run the application and test out the code! Here’s Application class that loads the XML file to instantiate the Spring Container and execute a few queries.

Application.java

package com.jcg.examples.test;


import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;

import com.jcg.examples.entity.Address;
import com.jcg.examples.entity.Person;
import com.jcg.examples.repo.AddressRepo;
import com.jcg.examples.repo.PersonRepo;


public class Application
{
		public static void main(String[] args)
		{
				ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new ClassPathResource("spring-config.xml").getPath());
				PersonRepo personRepo = context.getBean(PersonRepo.class);
				AddressRepo addressRepo = context.getBean(AddressRepo.class);
				
				Person personAchilles = new Person();
				personAchilles.setPersonId(1l);
				personAchilles.setName("Achilles");
				personRepo.save(personAchilles);
				Person personHektor = new Person();
				personHektor.setPersonId(2l);
				personHektor.setName("Hektor");
				
				Address address = new Address(1,"221b Baker Street","London NW1","London",12345l);
				List<Address> addresses = personHektor.getAddresses();
				addresses.add(address);
				personAchilles.setAddresses(addresses);				
				
				addressRepo.save(address);
				personRepo.save(personHektor);
				
				Iterable<Person> personList = personRepo.findAll();
				System.out.println("Person List : ");
				for (Person person : personList)
        {
		        System.out.println(person);
        }
				
				System.out.println("Person Record with name Hektor  is "+personRepo.searchByName("Hektor"));
				
				context.close();

		}
}

In the Application we create two instances of Person and persist them. However, the second instance also has a linked Address instance to it, which we persist separately by calling the save method of the AddressRepo class.

Then we iterate all the elements stored in the Person collection. We have also successfully searched for the Person named Hektor from the collection using custom query and the @Query annotation.

Here’s the sample output of the program:

Person List : 
Person [personId=1, name=Achilles, age=0, addresses=[]]
Person [personId=2, name=Hektor, age=0, addresses=[Address [address=221b Baker Street, city=London NW1, state=London, zipcode=12345]]]
Person Record with name Hektor  is [Person [personId=2, name=Hektor, age=0, addresses=[Address [address=221b Baker Street, city=London NW1, state=London, zipcode=12345]]]]

2. Download the Source Code

Here we demonstrated how to configure and manage a MongoDb using Spring Data.

Download
You can download the source code of this example here: SpringDataMongoDbExample.zip

Chandan Singh

Chandan holds a degree in Computer Engineering and is a passionate software programmer. He has good experience in Java/J2EE Web-Application development for Banking and E-Commerce Domains.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button