Visão geral
Neste guia, você pode aprender como usar a Extensão MongoDB para Hibernar ORM para executar transações. As transações permitem que você execute uma série de operações que alteram os dados somente se toda a transação estiver confirmada.
No MongoDB, as transações são executadas dentro de sessões lógicas. Uma sessão é um agrupamento de operações de leitura ou escrita relacionadas que você deseja executar sequencialmente. As sessões permitem consistência causal para um grupo de operações e permitem executar operações em uma transação compatível com ACID, que é uma transação que atende a uma expectativa de atomicidade, consistência, isolamento e durabilidade.
A extensão Hibernate ORM suporta as seguintes APIs para gerenciar sessões e transações:
Hibernar
Session: Permite a você utilizar a API doorg.hibernate.Transactionpara agrupar suas operações do banco de dados . Para saber mais, consulte API de transação Hibernate no guia do usuário do Hibernate ORM.Jakarta Persistence
EntityManager: Instrui o ORM do Hibername a gerenciar umSessioninternamente e permite que você utilize a API dojakarta.persistence.EntityTransactionpara agrupar suas operações de banco de dados . Para saber mais, consulte o pacote jakarta.persistence na documentação do Jakarta EE.
Dados de amostra
Os exemplos neste guia usam a entidade Movie, que representa a coleção sample_mflix.movies dos conjuntos de dados de amostra do Atlas. A entidade Movie tem a seguinte definição:
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 como criar um aplicativo Java que usa a Extensão MongoDB para Hibernate ORM para interação com esta coleção de amostra do MongoDB, veja o Get Started tutorial.
Criar uma sessão
Para a interação com os dados do MongoDB, você deve executar todas as operações do banco de dados em uma sessão. Esta seção mostra como gerenciar uma sessão do banco de dados das seguintes maneiras:
Use uma sessão do Hibernar: Use a API nativa do Hibernado para criar um
Sessiona partir de umSessionFactoryUse um JPA EntityManager: Use a API de persistência de Jakarta para criar um
EntityManagera partir de umEntityManagerFactory
Usar uma Sessão de hibernação
Dica
Antes de utilizar um Session, você deve criar um arquivo HibernateUtil.java que configura um SessionFactory. Para aprender mais, veja a etapa Configure seu aplicativo do tutorial de Introdução.
Para iniciar um Session de hibernação, execute as seguintes etapas:
Recupere um
SessionFactoryda sua classe de utilidadeHibernateUtilusando o métodogetSessionFactory(). OSessionFactoryarmazena sua configuração de conexão MongoDB e pode abrir novas sessões de banco de dados .Crie um
Sessionchamando o métodoopenSession()em sua instância doSessionFactory.Após executar as operações do banco de dados , feche o
SessionFactorye oSessionusando o métodoclose()em ambas as instâncias.
O exemplo a seguir executa uma query de banco de dados em uma sessão e recupera um documento que tem um valor title de "Erin Brockovich" da coleção 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
Você também pode usar a declaração try-with-resources do Java para simplificar a lógica de gerenciamento da sessão e fechar automaticamente a sessão, conforme mostrado no código a seguir:
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();
Usar um JPA EntityManager
Dica
Antes de utilizar um EntityManager, você deve criar um arquivo persistence.xml que declara uma unidade de persistência. Para aprender mais, veja o Tutorial usando APIs padrão JPA na documentação do ORM do Hibernate.
Para iniciar uma API de Persistência de Jacarta (JPA) EntityManager, execute as seguintes etapas:
Crie um
EntityManagerFactorya partir do seu arquivopersistence.xmlchamando o métodocreateEntityManagerFactory(), que cria umSessionFactoryinternamente.Crie um
EntityManagerchamando o métodocreateEntityManager()em sua instância doEntityManagerFactory, que cria umSessioninternamente.Após executar as operações do banco de dados , feche seu
EntityManagerFactoryeEntityManagerchamando o métodoclose()em ambas as instâncias.
O exemplo a seguir executa uma query de banco de dados em um gerente de entidade e recupera documentos que têm um valor year de 1929 da coleção 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
In Jakarta Persistence v3.1 ou posterior, você pode usar a declaração try-with-resources do Java para fechar automaticamente o EntityManager, conforme mostrado na seção Sessão de hibernação.
Executar uma transação
Para modificar dados MongoDB, você deve executar todas as operações de gravação em uma transação. Esta seção mostra como gerenciar uma transação das seguintes maneiras:
Use uma transação Hibernar: Use a API
org.hibernate.Transactionnativa do Hibernado para iniciar uma transação a partir de umSessionUse uma EntityTransaction JPA: use a API
jakarta.persistence.EntityTransactionpara iniciar uma transação a partir de umEntityManager
Usar uma transação hibernar
Para iniciar um Transaction de hibernação, chame o método beginTransaction() em uma instância Session. Depois de executar as operações e usar o método persist() para registrar suas alterações na sessão, realize a confirmação da transação chamando o método commit().
O exemplo a seguir utiliza uma transação para executar as seguintes operações na coleção sample_mflix.movies:
Cria uma nova entidade
Moviee a insere como um documento na coleçãoAtualiza o campo
castde um documento que tem um valortitlede"Black Swan"
As linhas destacadas iniciam a transação e a confirmação:
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();
Usar uma EntityTransaction JPA
Para criar um EntityTransaction JPA, chame o método getTransaction() no seu EntityManager. Este método recupera um EntityTransaction, que envolve o hibernação subjacente Transaction. Em seguida, chame o método begin() para iniciar a transação. Depois de executar as operações e usar o método persist() para registrar suas alterações com o gerente de entidades, faça a confirmação da transação chamando o método commit().
O exemplo a seguir usa um EntityTransaction para excluir um documento da coleção sample_mflix.movies e, em seguida, insere um novo documento que tem um valor de title de "The Favourite". As linhas destacadas iniciam e fazem a confirmação da transação:
// 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();
Tratamento de erros de transação
Para descartar todas as alterações de dados de uma transação, chame o método rollback() em um Hibernar Transaction ou um EntityTransaction JPA. Depois de chamar esse método, o ORM do Hibername reverte as alterações não confirmadas e limpa o contexto de persistência.
O exemplo a seguir reverte a transação se o código gerar um erro. Selecione a aba Hibernate Transaction ou JPA EntityTransaction para ver o código correspondente:
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(); }
Informações adicionais
Para saber mais sobre sessões e gerentes de entidade, consulte Contexto de Persistência na documentação ORM do Hibernate.
Para saber mais sobre transações, consulte Transações na documentação do ORM do Hibernate.