Como injetar EntityManager com Spring: @PersistenceContext x Construtor

A diferença entre usar @PersistenceContext e injetar EntityManager via construtor depende principalmente do mecanismo de injeção de dependência do Spring e da forma como o EntityManager é gerenciado.


1️⃣ Usando @PersistenceContext

<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span>
<span>import</span> <span>javax.persistence.PersistenceContext</span><span>;</span>
<span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span>
<span>@Repository</span>
<span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span>
<span>@PersistenceContext</span>
<span>private</span> <span>EntityManager</span> <span>entityManager</span><span>;</span>
<span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span>
<span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span>
<span>}</span>
<span>}</span>
<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span>
<span>import</span> <span>javax.persistence.PersistenceContext</span><span>;</span>
<span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span>

<span>@Repository</span>
<span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span>

    <span>@PersistenceContext</span>
    <span>private</span> <span>EntityManager</span> <span>entityManager</span><span>;</span>

    <span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span>
        <span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span>
    <span>}</span>
<span>}</span>
import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Repository; @Repository public class MeuRepositorio { @PersistenceContext private EntityManager entityManager; public void salvar(Entidade entidade) { entityManager.persist(entidade); } }

Enter fullscreen mode Exit fullscreen mode

Como funciona?

  • @PersistenceContext é a anotação padrão do JPA para injeção do EntityManager.
  • O Spring detecta essa anotação e injeta um EntityManager gerenciado pelo contexto de persistência.
  • Normalmente, esse EntityManager é transacional e atrelado à transação do Spring.

Vantagens

️ Garante que o EntityManager é gerenciado corretamente pelo Spring.

️ Facilita a integração com o JPA sem necessidade de configuração adicional.

️ Garante que a instância do EntityManager pertence ao escopo correto da transação.

Desvantagens

Não permite injeção via construtor (dificulta testes unitários sem Spring).

Não pode ser usado em atributos final (impede imutabilidade).


2️⃣ Injetando EntityManager via Construtor

<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span>
<span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span>
<span>@Repository</span>
<span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span>
<span>private</span> <span>final</span> <span>EntityManager</span> <span>entityManager</span><span>;</span>
<span>public</span> <span>MeuRepositorio</span><span>(</span><span>EntityManager</span> <span>entityManager</span><span>)</span> <span>{</span>
<span>this</span><span>.</span><span>entityManager</span> <span>=</span> <span>entityManager</span><span>;</span>
<span>}</span>
<span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span>
<span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span>
<span>}</span>
<span>}</span>
<span>import</span> <span>javax.persistence.EntityManager</span><span>;</span>
<span>import</span> <span>org.springframework.stereotype.Repository</span><span>;</span>

<span>@Repository</span>
<span>public</span> <span>class</span> <span>MeuRepositorio</span> <span>{</span>

    <span>private</span> <span>final</span> <span>EntityManager</span> <span>entityManager</span><span>;</span>

    <span>public</span> <span>MeuRepositorio</span><span>(</span><span>EntityManager</span> <span>entityManager</span><span>)</span> <span>{</span>
        <span>this</span><span>.</span><span>entityManager</span> <span>=</span> <span>entityManager</span><span>;</span>
    <span>}</span>

    <span>public</span> <span>void</span> <span>salvar</span><span>(</span><span>Entidade</span> <span>entidade</span><span>)</span> <span>{</span>
        <span>entityManager</span><span>.</span><span>persist</span><span>(</span><span>entidade</span><span>);</span>
    <span>}</span>
<span>}</span>
import javax.persistence.EntityManager; import org.springframework.stereotype.Repository; @Repository public class MeuRepositorio { private final EntityManager entityManager; public MeuRepositorio(EntityManager entityManager) { this.entityManager = entityManager; } public void salvar(Entidade entidade) { entityManager.persist(entidade); } }

Enter fullscreen mode Exit fullscreen mode

Como funciona?

  • O Spring injeta o EntityManager diretamente no construtor da classe.
  • Funciona porque o Spring Boot gerencia o EntityManagerFactory e fornece um EntityManager apropriado como dependência.

Vantagens

️ Permite injeção via construtor, facilitando testes unitários sem Spring.

️ Torna os campos final, favorecendo imutabilidade e injeção de dependências explícita.

️ Reduz o acoplamento com a API do JPA (@PersistenceContext não é necessário).

Desvantagens

Depende da configuração automática do Spring para fornecer um EntityManager.

Se usado fora do contexto correto, pode resultar em TransactionRequiredException.


Qual Opção Escolher?

Critério @PersistenceContext Injeção via Construtor
Gerenciamento do Spring Sim (injeção automática) Sim (injeção automática)
Escopo da Transação Automático Depende do contexto do Spring
Facilidade de Teste Mais difícil (precisa de @Mock ou Spring) Mais fácil (injeção direta)
Imutabilidade Não suporta final Suporta final
Padrão Recomendado Antigo, mas ainda funcional Recomendado para Clean Architecture

Se você está seguindo boas práticas modernas (Clean Architecture, DDD, SOLID, imutabilidade), use injeção via construtor.

Se você precisa de compatibilidade com um código legado ou quer um EntityManager sempre atrelado ao contexto de persistência do JPA, @PersistenceContext é uma escolha válida.

原文链接:Como injetar EntityManager com Spring: @PersistenceContext x Construtor

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
Stop to have a rest, do not forget others still in the running.
停下来休息的时候,不要忘记别人还在奔跑
评论 抢沙发

请登录后发表评论

    暂无评论内容