Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Transacciones y Sesiones

En esta guía, puedes aprender a utilizar la extensión MongoDB para Hibernate ORM para realizar transacciones. Las transacciones te permiten ejecutar una serie de operaciones que modifican datos solo si la transacción completa se confirma.

En MongoDB, las transacciones se ejecutan dentro de sesiones lógicas. Una sesión es un grupo de operaciones de lectura o escritura relacionadas que deseas ejecutar de manera secuencial. Las sesiones permiten una coherencia causal para un grupo de operaciones y permiten ejecutar operaciones en una transacción compatible con ACID , que es una transacción que cumple con la expectativa de atomicidad, coherencia, aislamiento y durabilidad.

La extensión de Hibernate ORM admite las siguientes APIs para gestionar sesiones y transacciones:

  • Hibernar SessionPermite utilizar la API org.hibernate.Transaction para agrupar las operaciones de la base de datos. Para obtener más información, consulte API de Transacción Hibernate en la guía del usuario de Hibernate ORM.

  • Jakarta Persistence EntityManager: indica al Hibérnate ORM que gestione un Session internamente y le permite utilizar la API jakarta.persistence.EntityTransaction para agrupar las operaciones de su base de datos. Para obtener más información, consulta el paquete jakarta.persistence en la documentación de Jakarta EE.

Los ejemplos de esta guía utilizan la Movie entidad, que representa la sample_mflix.movies colección de los conjuntos de datos de muestra del Atlas. La Movie entidad tiene la siguiente definición:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
public Movie(String title, String plot, int year, List<String> cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
}

Para aprender a crear una aplicación Java que use la extensión MongoDB para Hibernate ORM para interactuar con esta colección de muestra de MongoDB, consulte Comenzar tutorial.

Para interactuar con los datos de MongoDB, debe ejecutar todas las operaciones de base de datos en una sesión. Esta sección muestra cómo administrar una sesión de base de datos de las siguientes maneras:

Tip

Antes de usar un Session, debes crear un archivo HibernateUtil.java que configure un SessionFactory. Para aprender más, consulta el paso Configura tu aplicación del tutorial de Introducción.

Para iniciar una Hibernate Session, realiza los siguientes pasos:

  1. Recupere un SessionFactory de su clase utilitaria HibernateUtil utilizando el método getSessionFactory(). El SessionFactory almacena tu configuración de conexión MongoDB y puede abrir nuevas sesiones de base de datos.

  2. Cree un Session llamando al método openSession() en su instancia SessionFactory.

  3. Después de ejecutar operaciones en la base de datos, cierra tu SessionFactory y Session utilizando el método close() en ambas instancias.

El siguiente ejemplo ejecuta una consulta de base de datos en una sesión y recupera un documento que tiene un valor title de "Erin Brockovich" de la colección sample_mflix.movies:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
session.close();
sf.close();
Title: Erin Brockovich, Year: 2000

También puedes utilizar la instrucción try-with-resources de Java para simplificar la lógica de gestión de sesiones y cerrar automáticamente la sesión, como se muestra en el siguiente código:

var sf = HibernateUtil.getSessionFactory();
try (Session session = sf.openSession()) {
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Erin Brockovich")
.getSingleResult();
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
}
sf.close();

Tip

Antes de usar un EntityManager, debes crear un archivo persistence.xml que declare una unidad de persistencia. Para aprender más, consulta el Tutorial utilizando APIs estándar JPA en la documentación de Hibernate ORM.

Para iniciar una EntityManager de la API de persistencia de Jakarta (JPA), realiza los siguientes pasos:

  1. Cree un EntityManagerFactory a partir de su archivo persistence.xml llamando al método createEntityManagerFactory(), que crea un SessionFactory internamente.

  2. Cree un EntityManager llamando al método createEntityManager() en su instancia de EntityManagerFactory, que crea un Session internamente.

  3. Después de ejecutar las operaciones de base de datos, cierre EntityManagerFactory y EntityManager llamando al método close() en ambas instancias.

El siguiente ejemplo ejecuta una consulta de base de datos en un administrador de entidades y recupera documentos que tienen un valor year de 1929 de la colección sample_mflix.movies:

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
var results = entityManager.createQuery("select m from Movie m where m.year = :y", Movie.class)
.setParameter("y", 1929)
.getResultList();
results.forEach(movie -> System.out.println(movie.getTitle()));
entityManager.close();
emf.close();
The Broadway Melody
Queen Kelly
Asphalt
Hallelujah
Disraeli
Applause
Lambchops

En Jakarta Persistence v3.1 o posterior, puedes usar la instrucción try-with-resources de Java para cerrar automáticamente el EntityManager, como se muestra en la sección Hibernate Session.

Para modificar los datos de MongoDB, debe ejecutar todas las operaciones de escritura en una transacción. Esta sección muestra cómo gestionar una transacción de las siguientes maneras:

Para iniciar un Hibernate Transaction, llama al método beginTransaction() en una instancia de Session. Después de ejecutar las operaciones y utilizar el método persist() para registrar tus cambios con la sesión, confirma la transacción llamando al método commit().

El siguiente ejemplo usa una transacción para realizar las siguientes operaciones en la colección sample_mflix.movies:

  • Crea una nueva entidad Movie y la inserta como un documento en la colección

  • Actualiza el campo cast de un documento que tiene un valor title de "Black Swan"

Las líneas resaltadas inician y confirman la transacción:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
var newMovie = new Movie();
newMovie.setTitle("Lady Bird");
newMovie.setYear(2017);
session.persist(newMovie);
var movie = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Black Swan")
.getSingleResult();
var currentCast = new ArrayList<>(movie.getCast());
currentCast.add("Winona Ryder");
movie.setCast(currentCast);
tx.commit();
session.close();
sf.close();

Para crear un/una JPA EntityTransaction, llama al método getTransaction() en tu EntityManager. Este método recupera un EntityTransaction, que envuelve el subyacente Hibernate Transaction. A continuación, llama al método begin() para iniciar la transacción. Después de ejecutar operaciones y de utilizar el método persist() para registrar los cambios con el administrador de entidades, confirmar la transacción llamando al método commit().

El siguiente ejemplo utiliza un EntityTransaction para borrar un documento de la colección sample_mflix.movies y luego insertar un nuevo documento que tenga un valor de título de "The Favourite". Las líneas resaltadas inician y confirman la transacción:

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
// Your ObjectId value might differ
Movie movieToDelete = entityManager.find(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
entityManager.remove(movieToDelete);
var addMovie = new Movie();
addMovie.setTitle("The Favourite");
addMovie.setYear(2018);
entityManager.persist(addMovie);
entityManager.getTransaction().commit();
entityManager.close();
emf.close();

Para descartar todos los cambios de datos de una transacción, llama al método rollback() en un Hibernate Transaction o en un JPA EntityTransaction. Después de llamar a este método, el Hibernate ORM revierte los cambios no confirmados y limpia el contexto de persistencia.

El siguiente ejemplo revierte la transacción si el código genera un error. Elija el Hibernate Transaction o la pestaña JPA EntityTransaction para ver el código correspondiente:

Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
session.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
EntityManager entityManager = emf.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
try {
tx.begin();
Movie movie = new Movie();
movie.setTitle("Control Alt Delete");
entityManager.persist(movie);
tx.commit();
} catch (Exception e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
e.printStackTrace();
} finally {
entityManager.close();
}

Para obtener más información sobre sesiones y administradores de entidades, consulta Contexto de Persistencia en la documentación de Hibernate ORM.

Para obtener más información sobre transacciones, consulta Transacciones en la documentación de Hibernate ORM.

Volver

Ejecutar consultas nativas

En esta página