Overview
En esta guía, aprenderá a usar la extensión MongoDB para Hibernate ORM para realizar transacciones. Las transacciones permiten ejecutar una serie de operaciones que modifican los datos solo si se confirma la transacción completa.
En MongoDB, las transacciones se ejecutan dentro de sesiones lógicas. Una sesión es una agrupación de operaciones de lectura o escritura relacionadas que se ejecutan secuencialmente. Las sesiones permiten la consistencia causal de un grupo de operaciones y ejecutarlas en una transacción compatible con ACID, que cumple con los requisitos de atomicidad, consistencia, aislamiento y durabilidad.
La extensión ORM de Hibernate admite las siguientes API para administrar sesiones y transacciones:
Hibernar
Session: Le permite usar la APIorg.hibernate.Transactionpara agrupar las operaciones de su base de datos. Para obtener más información, consulte API de transacciones de Hibernate en la guía del usuario de Hibernate ORM.Persistencia de
EntityManagerJakarta: Indica al ORM de Hibernate que administre unSessioninternamente y permite usar lajakarta.persistence.EntityTransactionAPI para agrupar las operaciones de la base de datos. Para obtener más información, consulte el paquete jakarta.persistence en la documentación de Jakarta EE.
Datos de muestra
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; public class Movie { 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 Tutorial de introducción.
Crear una sesión
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:
Utilice una sesión de Hibernate: utilice la API nativa de Hibernate para crear un a partir de
SessionunSessionFactoryUtilice un EntityManager JPA: utilice la API de persistencia de Jakarta para crear un a partir
EntityManagerde unEntityManagerFactory
Utilice una sesión de hibernación
Tip
Antes de usar Session un, debe crear un HibernateUtil.java archivo que configure SessionFactory un. Para obtener más información, consulte el paso "Configurar su aplicación" del tutorial "Comenzar".
Para iniciar una Hibernate Session, realiza los siguientes pasos:
Recupere un
SessionFactoryde su clase de utilidadHibernateUtilmediante el métodogetSessionFactory(). ElSessionFactoryalmacena la configuración de su conexión de MongoDB y permite abrir nuevas sesiones de base de datos.Cree un
Sessionllamando al métodoopenSession()en su instanciaSessionFactory.Después de ejecutar operaciones en la base de datos, cierra tu
SessionFactoryySessionutilizando el métodoclose()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 puede utilizar la declaración try-with-resources de Java para simplificar la lógica de gestión de la sesión y cerrar la sesión automáticamente, 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();
Utilice un EntityManager JPA
Tip
Antes de usar un,EntityManager debe crear un persistence.xml archivo que declare una unidad de persistencia. Para obtener más información, consulte el Tutorial sobre el uso de las API estándar de JPA en la documentación de Hibernate ORM.
Para iniciar una API de persistencia de Jakarta (JPA) EntityManager, realice los siguientes pasos:
Cree un
EntityManagerFactorya partir de su archivopersistence.xmlllamando al métodocreateEntityManagerFactory(), que crea unSessionFactoryinternamente.Cree un
EntityManagerllamando al métodocreateEntityManager()en su instanciaEntityManagerFactory, lo que crea unSessioninternamente.Después de ejecutar las operaciones de base de datos, cierre
EntityManagerFactoryyEntityManagerllamando al métodoclose()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, puede usar la declaración try-with-resources de Java para cerrar automáticamente EntityManager el, como se muestra en la sección Sesión de hibernación.
Ejecutar una transacción
Para modificar 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:
Utilice una transacción de Hibernate: utilice la API nativa de Hibernate
org.hibernate.Transactionpara iniciar una transacción desde unaSessionUtilice una EntityTransaction JPA: utilice la
jakarta.persistence.EntityTransactionAPI para iniciar una transacción desde unaEntityManager
Utilice una transacción de Hibernate
Para iniciar una instancia de Hibernate Transaction, llame al método beginTransaction() en una instancia Session. Después de ejecutar las operaciones y usar el método persist() para registrar los cambios en la sesión, confirme 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
Moviey la inserta como un documento en la colecciónActualiza el campo
castde un documento que tiene un valortitlede"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();
Utilice una entidad JPA Transaction
Para crear un JPA EntityTransaction, llame al método getTransaction() en su EntityManager. Este método recupera un EntityTransaction, que encapsula el Hibernate subyacente Transaction. A continuación, llame al método begin() para iniciar la transacción. Después de ejecutar las operaciones y usar el método persist() para registrar los cambios en el administrador de entidades, confirme la transacción llamando al método commit().
El siguiente ejemplo usa un EntityTransaction para eliminar un documento de la colección sample_mflix.movies y, a continuación, inserta un nuevo documento cuyo valor de título es "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();
Gestión de errores de transacción
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. Seleccione el Hibernate Transaction o 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(); }
Información Adicional
Para obtener más información sobre sesiones y administradores de entidades, consulte Contexto de persistencia en la documentación de Hibernate ORM.
Para obtener más información sobre las transacciones, consulte Transacciones en la documentación de Hibernate ORM.