A logo showing the text blog.marcnuri.com
English
Inicio»Java»Spring-data + Mongo: Secuencia autoincremental en MongoDB mediante un servicio de Spring

Entradas Recientes

  • Fabric8 Kubernetes Client 7.2.0 está disponible!
  • Conectarse a un servidor MCP con JavaScript y AI SDK
  • Conectarse a un servidor MCP con JavaScript y LangChain.js
  • El Futuro de las Herramientas para Desarrolladores en la era de la IA
  • Conectarse a un servidor Model Context Protocol (MCP) con Java y LangChain4j

Categorías

  • Antiguo
  • Front-end
  • Go
  • Herramientas
  • Industria y negocios
  • Inteligencia Artificial
  • Java
  • JavaScript
  • Operaciones
  • Personal
  • Proyectos personales

Archivos

  • mayo 2025
  • abril 2025
  • marzo 2025
  • febrero 2025
  • enero 2025
  • diciembre 2024
  • noviembre 2024
  • agosto 2024
  • junio 2024
  • mayo 2024
  • abril 2024
  • marzo 2024
  • febrero 2024
  • enero 2024
  • diciembre 2023
  • noviembre 2023
  • octubre 2023
  • septiembre 2023
  • agosto 2023
  • julio 2023
  • junio 2023
  • mayo 2023
  • abril 2023
  • marzo 2023
  • febrero 2023
  • enero 2023
  • diciembre 2022
  • noviembre 2022
  • octubre 2022
  • agosto 2022
  • julio 2022
  • mayo 2022
  • marzo 2022
  • febrero 2022
  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021
  • diciembre 2020
  • octubre 2020
  • agosto 2020
  • junio 2020
  • mayo 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • noviembre 2019
  • octubre 2019
  • julio 2019
  • diciembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • marzo 2018
  • febrero 2018
  • noviembre 2017
  • octubre 2017
  • agosto 2017
  • julio 2017
  • enero 2017
  • julio 2016
  • enero 2016
  • diciembre 2015
  • noviembre 2015
  • diciembre 2014
  • marzo 2014
  • febrero 2011
  • junio 2008
  • mayo 2008
  • abril 2008
  • enero 2008
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007

Spring-data + Mongo: Secuencia autoincremental en MongoDB mediante un servicio de Spring

2017-08-21 en Java etiquetado Base de Datos / Java / Mongo / MongoDB / Secuencia / Spring Framework / Spring Data por Marc Nuri | Última actualización: 2021-03-18

Introducción

En este post mostraré cómo asignar un valor de una secuencia incrementada de forma automática a un campo empleando una colección de mongo. Para ello emplearemos la misma técnica que se muestra en el tutorial de mongodb.com pero con métodos puramente Java.

Es importante reseñar que este valor no debería de emplearse como identificador único del documento, Mongo ya dispone de mejores métodos para asignar identificadores a documentos, y por lo general sería una mala práctica. Por otro lado, en sistemas distribuidos o en bases de datos con una enorme cantidad de documentos, tampoco debería de emplearse esta metodología.

Este sistema es útil cuando hay que asignar identificadores públicos o de fácil memorización para ser empleados por usuarios del sistema (números de facturas, número de proveedor, número de envío, etc.)

Código para actualizar una secuencia en MongoDB desde Java de forma segura
Código para actualizar una secuencia en MongoDB desde Java de forma segura

Colección de secuencias

Del mismo modo que se muestra en el tutorial mencionado, vamos a disponer de un @Document para cada una de las secuencias que utilicemos. En este documento se alojará el último valor de la secuencia utilizado para cada una de ellas.

Es decir, para la versión propuesta en notación JSON:

1{
2    _id: "userid",
3    seq: 0
4}

Vamos a crear la siguiente clase Java:

1@Document(collection = "sequences")
2public class Sequence {
3  @Id
4  private String id;
5  private Long value;
6//....//
7}

Por otro lado, crearemos un servicio de Spring que nos permitirá obtener el siguiente valor de cada una de las secuencias de forma segura.

Para ello, en el tutorial original se emplea la siguiente función Javascript:

1function getNextSequence(name) {
2   var ret = db.counters.findAndModify(
3          {
4            query: { _id: name },
5            update: { $inc: { seq: 1 } },
6            new: true
7          }
8   );
9
10   return ret.seq;
11}

Esta función la añadimos a un @Service de Spring que podemos emplear cuando guardemos el documento que hará uso de la secuencia:

1@Service
2public class SequenceService {
3  @Autowired
4  private MongoOperations mongo;
5
6//...//
7
8  public Long getNextValue(String sequenceId) {
9    //https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/
10    final Sequence sequence = mongo.findAndModify(
11        query(where("_id").is(sequenceId)),
12        new Update().inc("value",1),
13        options().returnNew(true).upsert(true),
14        Sequence.class);
15    return sequence.getValue();
16  }
17}

La función anterior podría emplearse posteriormente en otro servicio o repositorio a la hora de guardar un documento (e.g. una factura):

1@Service
2public InvoiceService {
3
4    @Autowired
5    private SequenceService sequenceService;
6
7    @Autowired
8    private InvoiceRepository invoiceRepository;
9
10//...//
11
12    public Invoice insert(Invoice newInvoice) {
13//...//
14        newInvoice.setPublicId(sequenceService.getNextValue("INV");
15//...//
16         return invoiceRepository.insert(newInvoice)
17    }
18
19//...//
20
21}

Función findAndModify

La función principal que se está empleando es findAndModify() que modifica y devuelve un único documento . Es importante señalar que la función debería de aplicarse filtrando sobre un campo que permita seleccionar la secuencia de forma unívoca. En este caso, localizaremos la secuencia por “_id”.

El trozo de código new Update().inc(“value”,1) incrementará unitariamente el campo “value”.

La opción returnNew(true) hará que la función devuelva el nuevo documento en lugar del original.

La opción upsert(true) creará un nuevo documento si la secuencia indicada no existe previamente.

Descargar código fuente

Podéis encontrar un proyecto de muestra con el código mostrado en este tutorial que cuenta con un @RestController para recuperar valores de secuencias y un test unitario para comprobar que se generan y almacenan correctamente en el siguiente enlace:

https://github.com/marcnuri-demo/spring-mongo-sequences

Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Navegador de artículos
Spring-boot como un servicio en LinuxIntegrando Angular y Spring Boot mediante Gradle
© 2007 - 2025 Marc Nuri