JPA e Hibernate

Named queries em arquivos externos

Você sabia que as Named Queries são muito importantes dentro do JPA? E que nem todo mundo as usa porque acha ruim colocá-las nas classes de entidades do sistema?

Neste artigo vou te mostrar uma solução simples para este problema das consultas ficarem nas classes do sistema, mostrando como podemos fazer para que elas fiquem em um arquivo externo, mais fácil de ler e manter.

Antes, deixa eu te contar que as Named Queries são as consultas estáticas do seu sistema. O que isso significa? Que são as buscas que as cláusulas de condição não irão mudar.

Por exemplo, em uma determinada tela do sistema você pode informar dois filtros para pesquisar uma pessoa, o código ou o CPF. Isso significa que sua consulta terá que se adaptar em tempo de execução, uma hora fará algo como:

select p from Pessoa
  where p.codigo = :codigo

E em outro momento:

select p from Pessoa
  where p.cpf = :cpf

E esse é um exemplo muito simples, poderíamos ter muitas outras cláusulas combinadas ali também para criar uma consulta dinâmica ou dynamic query.

Já uma named query não irá mudar nunca no sistema. Mas atenção, esse não mudar significa não adicionar ou remover cláusulas, os valores dos parâmetros podem variar. Ok?

Criei um sistema financeiro muito simples, com apenas alguns testes de integração para demonstrar essa utilização. Ele possui apenas duas entidades, Pessoa e Lancamento. Eu vou demonstrar algumas consultas em ambas as classes e deixo para você treinar, implementar algumas consultas extras nesse modelo, ok?

Você pode acessar o código aqui.

Para adicionar as named queries em arquivos, precisamos realizar alguns passos muito simples.

Primeiro, criar o arquivo que irá conter a consulta JPQL. Para este projeto, coloquei em META-INF/consultas/pessoas.xml as consultas para a entidade Pessoa e em META-INF/consultas/lancamentos.xml para a entidade Lancamento.

Mas você pode definir da forma que quiser, pode pensar em agrupar suas consultas por módulos do sistema, funcionalidades, etc. Enfim, o nome do arquivo está ali para te ajudar, você define o que quer agrupar ali.

Veja o conteúdo do arquivo pessoas.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"
  version="2.1">
  <named-query name="Pessoa.todas">
    <query>
      FROM
      Pessoa p
    </query>
  </named-query>
</entity-mappings>

E o conteúdo do arquivo lancamentos.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"
  version="2.1">
  <named-query name="Lancamento.descricoesQueContem">
    <query>
      SELECT distinct descricao FROM Lancamento
      WHERE upper(descricao) like upper(:descricao)
    </query>
  </named-query>
  
  <named-query name="Lancamento.todos">
    <query>
      FROM
      Lancamento l
    </query>
  </named-query>
</entity-mappings>

Repare que eu posso ter mais de uma named query dentro do mesmo arquivo.

Para que o entity manager consiga ler esses arquivos e carregar essas queries, é necessário adicionar a seguinte tag no persistence.xml:

<persistence-unit name="financeiroPU" transaction-type="RESOURCE_LOCAL">
   <mapping-file>META-INF/consultas/pessoas.xml</mapping-file>
   <mapping-file>META-INF/consultas/lancamentos.xml</mapping-file>

   <!-- Restante do arquivo...-->

Pronto, agora é só utilizar normalmente, da mesma forma que usaríamos se estivesse dentro da entidade. Por exemplo, para executar a consulta Lancamento.descricoesQueContem, basta ter o código:

TypedQuery<String> query = this.manager.createNamedQuery("Lancamento.descricoesQueContem", String.class);
query.setParameter("descricao", "%água%");
List<String> descricoes = query.getResultList();

Deixe seu comentário sobre o que você achou e me fale se você já usa Named Queries em seus projetos, e se vai migrar para arquivos externos a partir de agora.

Acesse ou baixe o código-fonte completo deste artigo no GitHub.

Para aprender mais sobre JPA 2 com Hibernate, conheça nosso curso online de Persistência de dados com JPA e Hibernate, que é completo e substitui a necessidade de cursos presenciais.

Graduado em Engenharia Elétrica pela Universidade Federal de Uberlândia e detentor das certificações LPIC-1, SCJP e SCWCD.

Olá,

o que você achou deste conteúdo? Conte nos comentários.

Junte-se a mais de 100.000 pessoas

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Você se Inscreveu com Sucesso!