leandromoraesrj / sincad-backend

PROJETO BASE DE EXEMPLO USANDO AS MELHORES PRATICAS DE DESENVOLVIMENTO
0 stars 0 forks source link

Padrão Specification e uso de Metamodel #41

Open leandromoraesrj opened 1 year ago

leandromoraesrj commented 1 year ago

As especificações são construídas sobre a Criteria API.

É necessário adicionar as dependências:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jpamodelgen</artifactId>
</dependency>

OBS: jpamodelgen irá gerar classes de metamodelo estático de nossas entidades, podemos usar Entity.campo em nossas consultas de critérios em vez de usar diretamente nomes de campo de string de nossas entidades. Um grande benefício disso é que as consultas que usam o metamodelo evoluem com as entidades e são muito mais fáceis de refatorar do que as consultas de string;

ATENÇÃO: NÃO CONSEGUI RODAR O METAMODEL.

Referência:https://www.baeldung.com/hibernate-criteria-queries-metamodel

public abstract class PaisSpec {
    public static Specification<Pais> byExample(Example<Pais> example) {
        return (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, cb, example));

            return cb.and(predicates.toArray(new Predicate[0]));
        };
    }
default boolean exists(PaisRequestDTO filter, boolean vigente) {
    return getRepository().count((vigente ? PaisSpec.isVigente() : PaisSpec.isHistorico())
            .and(PaisSpec.byExample(Example.of(getMapper().toEntity(filter), getExampleMatcher())))) > 0L;
}

Referência:https://reflectoring.io/spring-data-specifications/