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! 🎯

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay