Consultas de critério usando o metamodelo JPA

Consultas de critério usando o metamodelo JPA

1. Visão geral

Neste tutorial, discutiremos como usar as classes metamodelo estático JPA ao escrever consultas de critérios no Hibernate.

Precisaremos de um conhecimento básico dos critérios de consulta das APIs no Hibernate, portanto, verifique nosso tutorial emCriteria Queries para obter mais informações sobre este tópico, se necessário.

2. Por que o metamodelo JPA?

Freqüentemente, quando escrevemos uma consulta de critério, precisamos fazer referência a classes de entidade e seus atributos.

Agora, uma das maneiras de fazer isso é fornecer os nomes dos atributos como seqüências de caracteres. Mas, isso tem várias desvantagens.

Por um lado, precisamos procurar os nomes dos atributos da entidade. E, caso um nome de coluna seja alterado posteriormente no ciclo de vida do projeto, precisamos refatorar cada consulta em que o nome está sendo usado.

OJPA Metamodel foi introduzido pela comunidade para evitar essas desvantagens e fornecer acesso estático aos metadados das classes de entidade gerenciadas.

3. Classe de entidade

Vamos considerar um cenário em que estamos construindo um sistema de Gerenciamento do Portal do Aluno para um de nossos clientes e surge um requisito para fornecer funcionalidade de pesquisa emStudents com base no ano de graduação.

Primeiro, vamos dar uma olhada em nossa classeStudent:

@Entity
@Table(name = "students")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "grad_year")
    private int gradYear;

    // standard getters and setters
}

4. Gerando classes de metamodelos JPA

Em seguida, precisamos gerar as classes do metamodelo e, para esse propósito, usaremos a ferramenta geradora de metamodelo fornecida porJBoss. O JBoss é apenas uma das muitas ferramentas disponíveis para gerar o metamodelo. Outras ferramentas adequadas incluemEclipseLink,OpenJPA eDataNucleus.

Para usar a ferramenta JBoss, precisamos adicionarlatest dependency em nosso arquivopom.xml, e a ferramenta irá gerar as classes de metamodelo assim que acionarmos o comando maven build:


    org.hibernate
    hibernate-jpamodelgen
    5.3.7.Final

Note que precisamosadd the target/generated-classes folder to the classpath of our IDE, pois por padrão, as classes serão geradas apenas nesta pasta.

5. Classes estáticas de metamodelos JPA

Com base na especificação JPA, uma classe gerada residirá no mesmo pacote que a classe de entidade correspondente e terá o mesmo nome com um "” (underscore) at the end. So, the metamodel class generated for the Student class will be *Studentareia adicionado será semelhante a:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Student.class)
public abstract class Student_ {

    public static volatile SingularAttribute firstName;
    public static volatile SingularAttribute lastName;
    public static volatile SingularAttribute id;
    public static volatile SingularAttribute gradYear;

    public static final String FIRST_NAME = "firstName";
    public static final String LAST_NAME = "lastName";
    public static final String ID = "id";
    public static final String GRAD_YEAR = "gradYear";
}

6. Usando classes de metamodelo JPA

We can use the static metamodel classes in the same way we would use the String references to attributes. A API de consulta de critérios fornece métodos sobrecarregados que aceitam referênciasString, bem como implementações deAttribute interface.

Vejamos a consulta de critérios que buscará todos osStudents que se formaram em 2015:

//session set-up code
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery criteriaQuery = cb.createQuery(Student.class);

Root root = criteriaQuery.from(Student.class);
criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 2015));

Query query = session.createQuery(criteriaQuery);
List results = query.getResultList();

Observe como usamos a referênciaStudent_.gradYear  em vez de usar o nome da colunagrad_year convencional.

7. Conclusão

Neste artigo rápido, aprendemos como usar classes de metamodelo estáticas e por que elas podem ser preferidas em vez da forma tradicional de usarString referências conforme descrito anteriormente.

O código-fonte deste tutorial pode ser encontradoover on Github.