Spring Data MongoDB Auto Sequence ID example

摘要: In this tutorial, we will show you how to generate an auto-incrementing sequence id in MongoDB + Spring Data environment.

In this tutorial, we will show you how to generate an auto-incrementing sequence id in MongoDB + Spring Data environment.

Tools used in this project :

  1. Spring Data MongoDB 1.2.1.RELEASE
  2. MongoDB 2.4.5
  3. Eclipse 4.2
  4. Maven 3

At the end of this tutorial, if the collection name “hosting” is saved, a new auto-incrementing sequence id will be assigned. Below is the Java code snippet to generate the sequence id.

  public long getNextSequenceId(String key) {
	Query query = new Query(Criteria.where("_id").is(key));
        Update update = new Update();
	update.inc("seq", 1);
	FindAndModifyOptions options = new FindAndModifyOptions();
	options.returnNew(true);
	SequenceId seqId = 
            mongoOperation.findAndModify(query, update, options, SequenceId.class);
	return seqId.getSeq();
  }	

1. Project Structure

Review the project directory structure, a standard Maven project.

2. Maven Pom

In case you are interested at the project dependencies.

pom.xml
<project ...>
	<properties>
		<jdk.version>1.6</jdk.version>
		<spring.version>3.2.2.RELEASE</spring.version>
		<mongojavadriver.version>2.11.1</mongojavadriver.version>
		<springdata.version>1.2.1.RELEASE</springdata.version>
	</properties>
	<dependencies>
		<!-- Spring Core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- need this for @Configuration -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>
		<!-- Spring Data for MongoDB -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>${springdata.version}</version>
		</dependency>
		<!-- Java MongoDB Driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>${mongojavadriver.version}</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>SpringData</finalName>
		<plugins>
		  <plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.3.2</version>
			<configuration>
				<source>${jdk.version}</source>
				<target>${jdk.version}</target>
			</configuration>
		  </plugin>
		</plugins>
	</build>
</project>

3. Sequence Collection

We create a collection name “sequence” to store the auto increase sequence id. Refer to the SequenceDaoImpl.java below, it shows you the code to generate the sequence id.

Note
Create the “sequence” collection in your MongoDB first!

	db.sequence.insert({_id: "hosting",seq: 0})
SequenceId.java
package com.mkyong.seq.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "sequence")
public class SequenceId {
	@Id
	private String id;
	private long seq;
	//get, set, toString...
SequenceDao.java
package com.mkyong.seq.dao;
import com.mkyong.seq.exception.SequenceException;
public interface SequenceDao {
	long getNextSequenceId(String key) throws SequenceException;
SequenceDaoImpl.java
package com.mkyong.seq.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import com.mkyong.seq.exception.SequenceException;
import com.mkyong.seq.model.SequenceId;
@Repository
public class SequenceDaoImpl implements SequenceDao {
	@Autowired
	private MongoOperations mongoOperation;
	@Override
	public long getNextSequenceId(String key) throws SequenceException {
	  //get sequence id
	  Query query = new Query(Criteria.where("_id").is(key));
	  //increase sequence id by 1
	  Update update = new Update();
	  update.inc("seq", 1);
	  //return new increased id
	  FindAndModifyOptions options = new FindAndModifyOptions();
	  options.returnNew(true);
	  //this is the magic happened.
	  SequenceId seqId = 
            mongoOperation.findAndModify(query, update, options, SequenceId.class);
	  //if no id, throws SequenceException
          //optional, just a way to tell user when the sequence id is failed to generate.
	  if (seqId == null) {
		throw new SequenceException("Unable to get sequence id for key : " + key);
	  return seqId.getSeq();
SequenceException.java
package com.mkyong.seq.exception;
public class SequenceException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	private String errCode;
	private String errMsg;
	//get, set...
	public SequenceException(String errMsg) {
		this.errMsg = errMsg;

4. Get the Sequence ID

To get the sequence id, uses sequenceDao.getNextSequenceId("key").

HostingBo.java
package com.mkyong.hosting.bo;
import com.mkyong.seq.exception.SequenceException;
public interface HostingBo {
	void save(String name) throws SequenceException;
HostingBoImpl.java
package com.mkyong.hosting.bo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mkyong.hosting.dao.HostingDao;
import com.mkyong.hosting.model.Hosting;
import com.mkyong.seq.dao.SequenceDao;
import com.mkyong.seq.exception.SequenceException;
@Service
public class HostingBoImpl implements HostingBo {
	private static final String HOSTING_SEQ_KEY = "hosting";
	@Autowired
	private SequenceDao sequenceDao;
	@Autowired
	private HostingDao hostingDao;
	@Override
	public void save(String name) throws SequenceException {
		Hosting hosting = new Hosting();
		hosting.setId(sequenceDao.getNextSequenceId(HOSTING_SEQ_KEY));
		hosting.setName(name);
		hostingDao.save(hosting);
		System.out.println(hosting);

5. Testing

Run a simple test.

package com.mkyong;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.mkyong.config.AppConfig;
import com.mkyong.hosting.bo.HostingBo;
import com.mkyong.seq.exception.SequenceException;
public class App {
  public static void main(String[] args) {
	ApplicationContext ctx = 
            new AnnotationConfigApplicationContext(AppConfig.class);
	HostingBo hostingBo = (HostingBo) ctx.getBean("hostingBoImpl");
	try {
		hostingBo.save("cloud.google.com");
		hostingBo.save("heroku.com");
		hostingBo.save("cloudbees.com");
	} catch (SequenceException e) {
		System.out.println(e.getErrMsg());

Output – Java console

Hosting [id=1, name=cloud.google.com]
Hosting [id=2, name=heroku.com]
Hosting [id=3, name=cloudbees.com]

MongoDB console.

>mongo
> db.sequence.find()
{ "_id" : "hosting", "seq" : 3 }
> db.hosting.find()
{ "_id" : NumberLong(1), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "cloud.google.com" }
{ "_id" : NumberLong(2), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "heroku.com" }
{ "_id" : NumberLong(3), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "cloudbees.com" }
>

6. FAQs

Q. SequenceException – Unable to get sequence id for key : hosting ?
A. Remember to create the “sequence” collection!

	db.sequence.insert({_id: "hosting",seq: 0})

References

  1. MongoDB – Create an Auto-Incrementing Sequence Field

上一篇: Find out your Java heap memory size
下一篇: JSP jsessionid appear in CSS and JS link
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号