> For the complete documentation index, see [llms.txt](https://avbravo-2.gitbook.io/jmoordb/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://avbravo-2.gitbook.io/jmoordb/capitulo-4/introduccion-cap4/buscar-y-actualizar-automaticamente.md).

# Buscar y actualizar automaticamente

Muchas veces necesitamos incrementar el valor de un campo y retornarlo, por ejemplo para atributos autoincrementable.

Por ejemplo en bases de datos NoSQL como MongoDB no existe el concepto de autoincrementable.

**Métodos:**

| Métodos                                                                                | Bases de datos NoSQL |
| -------------------------------------------------------------------------------------- | -------------------- |
| public T findOneAndUpdate(String key, String value,String field,Integer... incremento) | MongoDB              |
| public T findOneAndUpdate(Document doc, String field, Integer... incremento)           | MongoDB              |
| public T findOneAndUpdate(Document doc, Document inc, Integer... incremento)           | MongoDB              |

**Parámetros**

**Key**: es el campo a buscar

**value**: el valor de ese campo

**field**: es el campo numérico a implementar

**incremento**: Opcional si no se pasa ningún valor incrementa en uno el campo

#### **Nota: A partir de la versión 0.2.9 se definió esta clase dentro de JMoordb, no es necesario declarar el entity**

![](/files/-Lc1WvizwF11F91bYfqc)

**Definir el entity: Autoincrementable**

```
@Getter
@Setter
public class Autoincrementable {
  @Id
  private String documento;
  private Integer contador;
  public Autoincrementable() {
  }

 public Autoincrementable(String documento, Integer contador) {
    this.documento = documento;
    this.contador = contador;
 }
  @Override
  public String toString() {
      return "Autoincrementable{" + "documento=" + documento + ", contador=" + contador + '}';
  }
}
```

## **Ejemplo 1:**&#x20;

Nota:

**Recuerde que no es necesario crear la clase Autoincrementable, este pertenece al framework.**

### Crear el Repository.

```
@Stateless
public class AutoincrementableRepository extends AbstractFacade<Autoincrementable> {

    @EJB
    MongoClientProvider mongoClientProvider;
    @Override
    protected MongoClient getMongoClient() {
       return mongoClientProvider.getMongoClient();
    }
    public AutoincrementableFacade(){
        super(Autoincrementable.class,"spardjsd","autoincrementable");
    }
    @Override
    public Object findById(String key, String value) {
       return search(key,value); 
    }
    @Override
    public Object findById(String key, Integer value) {
        return search(key,value);
    }

}
```

## **Autoincrementable como campo llave**

Contamos con una colección para almacenar facturas, y el atributo idfactura debe incrementarse automáticamente.

```
  @Getter
  @Setter
  public class Facturas {

  @Id
  private Integer idfactura;
  private Double ventas;

  public Facturas() {
  }

  public Facturas(Integer idfactura, Double ventas) {
      this.idfactura = idfactura;
     this.ventas = ventas;
  }

 @Override
  public String toString() {
      return "Facturas{" + "idfactura=" + idfactura + ", ventas=" + ventas + '}';
  }

 }
```

Crear una colección para que lleve el contador de los documentos y sus id que se usan en otras colecciones.

## **Controller**

Debemos inicializar el documento Autoincrementable, donde le indicamos el nombre del documento y el contador iniciar para llevar el control. Todos los documentos que se desee controlar su autoincrementable deben ser almacenados aquí. En el ejemplo lo inicializamos en 0.

```
 public void iniciarAutoicrementable(){
    try {
        Autoincrementable autoincrementable = new Autoincrementable("facturas", 0);
        if(autoincrementableRepository.save(autoincrementable)){
              System.out.println("guardado "); 
        }else{
            System.out.println("no se guardo "+autoincrementableRepository.getException());
        }


    } catch (Exception e) {
        System.out.println("iniciarAutoincrementable() "+e.getLocalizedMessage());

    }
}
```

**Si consultamos el documento**

```
db.autoincrementable.find().pretty()
{ "_id" : ObjectId("58861fdba6cca9146fbb2039"), "documento" : "facturas", "contador" : 0 }
```

**Guardar una factura**

```
public void guardarFactura() {
    try {
        //Busca el contador de facturas, lo incrementa en uno  y devuelve el objeto.
        Autoincrementable autoincrementable = new Autoincrementable();
        autoincrementable = autoincrementableFacade.findOneAndUpdate("documento", "facturas", "contador");
        Integer id = autoincrementable.getContador();

       //Guarda la factura
        Facturas facturas = new Facturas();
        facturas.setIdfactura(id);
        facturas.setVentas(5085.23);
        if (facturasRepository.save(facturas)) {
            System.out.println("guardado");
        } else {
            System.out.println("No se guardo " + facturasRepository.getException());
        }

    } catch (Exception e) {
        System.out.println("guardarFactura() " + e.getLocalizedMessage());
    }
}
```

Si consultamos la colección autoincrementable, podemos comprobar que se consulto el documento facturas y automáticamente se incremento en uno el valor del contador.

```
db.autoincrementable.find().pretty()                                                            
{
    "_id" : ObjectId("58861fdba6cca9146fbb2039"),
    "documento" : "facturas",
    "contador" : 1   
}
```

Si consultamos la colección facturas

```
db.facturas.find().pretty()                                                     
{
    "_id" : ObjectId("58863489a6cca91a36d27b3a"),
    "idfactura" : 1,
    "ventas" : 5085.23
}
```

## Ejemplo 2:

Autoincremantable en un atributo que no es llave primaria.

En el método save() , verificamos si no se ha creado un registro autoincrementable y lo creamos.

```
//verifica si no se ha creado el contador para proveedor
            Optional<Autoincrementable> autoincrementableOptional = autoincrementableRepository.find(new Document("documento", "proveedor"));
            if (!autoincrementableOptional.isPresent()) {

                Autoincrementable autoincrementable = new Autoincrementable("proveedor", 0);
                if (autoincrementableFacade.save(autoincrementable)) {
                }
            }

        Autoincrementable autoincrementable = new Autoincrementable();
        autoincrementable = autoincrementableRepository.findOneAndUpdate("documento", "proveedor", "contador");
        Integer id = autoincrementable.getContador();
        proveedor.setAutoincrementable(id);
            if (proveedorRepository.save(proveedor)) {
                JsfUtil.successMessage(rf.getAppMessage("info.save"));
                reset();
            } else {
                JsfUtil.successMessage("save() " + proveedorFacade.getException().toString());
            }
```

## Análisis de autoincrementables

Ejemplo del porque se implementa findOneAndUpdate()

Existe una colección de documentos donde se maneja un campo entero que funcionara como autoincrementable:

**Agenda**{"Id":1,"evento":"A"},

```
  {"Id":2,"evento":"B"},

  {"Id":3,"evento":"C"}
```

Si se elimina el evento 3,

**Agenda**{"Id":1,"evento":"A"},

```
   {"Id":2,"evento":"B"}
```

Cuando se desee insertar un documento con el {"evento":"D"}, se pueden producir algunas situaciones

\*\_1. Utilizar la función count() \*\_para conocer la cantidad de documentos que tiene la colección, este devolverá 2 y al sumarle 1 tendrá el valor de 3, que ya fue usado para el {"evento":"C"}. Al insertarlo quedaría de la siguiente manera:

**Agenda**

```
   {"Id":1,"evento":"A"},

   {"Id":2,"evento":"B"},

    {"Id":3,"evento":"D"}
```

**2. Si buscamos el ultimo documento de la colección**{"Id":2,"evento":"B"} , el valor del id es 2 al sumarle 1 quedara en 3, por lo tanto al insertar el evento {"evento":"D"} a la colección este tendría el valor de 3 para el id y este ya fue usado en el\
{"evento" :"C"}.

Al insertarlo quedaría de la siguiente manera:

**Agenda**{"Id":1,"evento":"A"},

```
    {"Id":2,"evento":"B"},

    {"Id":3,"evento":"D"}
```

De esta manera en la colección Agenda utilizara el valor que devuelva el campo valor de la colección

**Autoincrementable.**

El método findOneAndUpdate() busca el documento que cumpla la condición y realiza el incremento automático y devuelve el documento actualizado.

// incrementa en 1 el campo Valor

findOneAndUpdate("documento", "agenda", "valor");

// incrementa en 8 el campo Valor, le podemos indicar el valor que deseamos de incremento

findOneAndUpdate("documento", "agenda", "valor",8);

**Al insertarlo quedaría de la siguiente manera:**

Incrementa el campo valor y devuelve el documento actualizado**Autoincrementable{"documento":"agenda","valor":4}**

y este se asigna al id de la colección Agenda Agenda

```
     {"Id":1,"evento":"A"}

     {"Id":2,"evento":"B"}

     {"Id":4,"evento":"D"}**
```

**Código en Java:**

```
Autoincrementable autoincrementable = new Autoincrementable();

autoincrementable=autoincrementableRepository.findOneAndUpdate("documento", "agenda", "valor");

agenda.setIdagenda(autoincrementable.getValor());
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://avbravo-2.gitbook.io/jmoordb/capitulo-4/introduccion-cap4/buscar-y-actualizar-automaticamente.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
