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)