DEV Community

Uiratan Cavalcante
Uiratan Cavalcante

Posted on

EntityManager e Spring Data JPA

EntityManager, @PersistenceContext e @Transactional no Spring Data JPA

No Spring Data JPA, o EntityManager, a anotação @PersistenceContext e @Transactional trabalham juntos para gerenciar operações de persistência de forma eficiente e segura. Vamos entender cada um desses componentes e como eles se relacionam.


1️⃣ EntityManager: O Que É e De Onde Vem?

O EntityManager é a principal interface da Jakarta Persistence API (JPA) para gerenciar o ciclo de vida das entidades e interagir com o banco de dados. Ele permite operações como persistência, remoção e consultas.

📌 Origem do EntityManager:

  • O EntityManager vem da especificação JPA e é apenas uma interface.
  • Sua implementação concreta depende do provider JPA configurado no projeto (como Hibernate, EclipseLink ou OpenJPA).
  • No Spring Boot, o Hibernate é o provider padrão.

📌 Trecho da Interface JPA (EntityManager):

package jakarta.persistence; public interface EntityManager { void persist(Object entity); <T> T merge(T entity); void remove(Object entity); <T> T find(Class<T> entityClass, Object primaryKey); Query createQuery(String qlString); void close(); } 
Enter fullscreen mode Exit fullscreen mode

🔹 Como é apenas uma interface, o Hibernate fornece a implementação concreta.


1.1 Implementação do EntityManager no Hibernate

Se o Hibernate for o provider JPA, a implementação real do EntityManager será a classe org.hibernate.internal.SessionImpl.

📌 Classe real do Hibernate (SessionImpl):

package org.hibernate.internal; import jakarta.persistence.EntityManager; public class SessionImpl implements EntityManager { public void persist(Object entity) { // Implementação do persist no Hibernate } public <T> T merge(T entity) { // Implementação do merge no Hibernate } public void remove(Object entity) { // Implementação do remove no Hibernate } public void close() { // Implementação do close no Hibernate } } 
Enter fullscreen mode Exit fullscreen mode

🔹 O Hibernate usa SessionImpl para implementar EntityManager.


1.2 Como o Spring Obtém a Implementação do EntityManager?

O Spring Boot configura automaticamente um EntityManagerFactory, que cria instâncias do EntityManager.

📌 Fluxo de Criação do EntityManager no Spring:

JPA (Jakarta Persistence API) ↓ EntityManager (Interface) ↓ Provider JPA (Ex: Hibernate) ↓ Hibernate Session (Implementação real) ↓ Spring Boot cria EntityManagerFactory automaticamente ↓ EntityManager injetado nos Beans com @PersistenceContext 
Enter fullscreen mode Exit fullscreen mode

🔹 O Spring gerencia automaticamente o ciclo de vida do EntityManager.


2️⃣ @PersistenceContext: Injetando o EntityManager no Spring

O Spring fornece automaticamente um EntityManager gerenciado pelo container através da anotação @PersistenceContext.

📌 Exemplo de Uso:

import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; @Repository public class AutorRepositoryCustom { @PersistenceContext private EntityManager entityManager; public void salvar(Autor autor) { entityManager.persist(autor); } } 
Enter fullscreen mode Exit fullscreen mode

🔹 O Spring injeta o EntityManager automaticamente, e ele será gerenciado dentro do contexto da transação.


3️⃣ @Transactional: Garantindo a Consistência das Operações

A anotação @Transactional gerencia as transações automaticamente. No Spring Data JPA, ela garante que as operações sejam executadas dentro de uma única transação.

3.1 Como Funciona o @Transactional?

Quando um método anotado com @Transactional é chamado:

  1. O Spring abre uma transação no banco de dados.
  2. O EntityManager é associado à transação e pode executar operações.
  3. No final do método:
    • Se não houver erro, o Spring faz o commit da transação.
    • Se ocorrer uma exceção, o Spring faz rollback automaticamente.

📌 Exemplo de Uso do @Transactional:

import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class AutorService { @PersistenceContext private EntityManager entityManager; @Transactional public void criarAutor(Autor autor) { entityManager.persist(autor); } } 
Enter fullscreen mode Exit fullscreen mode

🔹 O Spring abre uma transação quando criarAutor é chamado e fecha no final.


3.2 Configurações Avançadas do @Transactional

A anotação @Transactional tem várias opções para personalizar o comportamento da transação:

Atributo Descrição
readOnly = true Otimiza consultas, garantindo que o método não fará alterações.
propagation Define como a transação se comporta caso outra já exista.
isolation Define o nível de isolamento (controle de concorrência).
rollbackFor Especifica quais exceções devem causar rollback.
noRollbackFor Define exceções que não devem causar rollback.

📌 Exemplo de Uso Avançado:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class) public void processarTransacao() { // Operação no banco de dados } 
Enter fullscreen mode Exit fullscreen mode

🔹 O método sempre rodará dentro de uma transação e fará rollback em qualquer exceção.


4️⃣ Exemplo Completo: Repositório, Service e Transações

📌 Criando um Repositório Customizado com EntityManager

import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; @Repository public class AutorRepositoryCustom { @PersistenceContext private EntityManager entityManager; public Autor buscarPorId(Long id) { return entityManager.find(Autor.class, id); } public void salvar(Autor autor) { entityManager.persist(autor); } } 
Enter fullscreen mode Exit fullscreen mode

📌 Criando um Serviço com @Transactional

import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class AutorService { private final AutorRepositoryCustom autorRepository; public AutorService(AutorRepositoryCustom autorRepository) { this.autorRepository = autorRepository; } @Transactional public void registrarAutor(Autor autor) { autorRepository.salvar(autor); } } 
Enter fullscreen mode Exit fullscreen mode

🔹 A transação começa quando o método registrarAutor é chamado e fecha no final.


Conclusão

EntityManager vem da JPA e é gerenciado pelo EntityManagerFactory no Spring Boot.

@PersistenceContext injeta o EntityManager automaticamente.

@Transactional garante que operações aconteçam dentro de uma transação.

✔ No Spring Boot, essas configurações são automáticas, mas podem ser personalizadas.

🚀 Agora você entende como EntityManager, @PersistenceContext e @Transactional funcionam no Spring Data JPA! 🎯

Top comments (0)