O meu código utilizando criteria estava dando erro no método and() e estava dizendo que ele não retornava um objeto do tipo Predicate, então fiz os casts que estavam no quickfix e compilou, mas na hora de rodar ele lançou um ClassCastException. Segue o meu código e o erro no console:
public List<Produto> buscaPorParametrosComCriteria(String nome, BigDecimal preco, LocalDate dataCadastro){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Produto> query = builder.createQuery(Produto.class);
Root<Produto> from = query.from(Produto.class);
Predicate filtro = (Predicate) builder.and();
if(nome != null && !nome.trim().isEmpty()) {
filtro = (Predicate) builder.and( (Expression<Boolean>) filtro, builder.equal(from.get("nome"), nome));
}
if(preco != null) {
filtro = (Predicate) builder.and( (Expression<Boolean>) filtro, builder.equal(from.get("nome"), nome));
}
if(dataCadastro != null) {
filtro = (Predicate) builder.and((Expression<Boolean>) filtro, builder.equal(from.get("nome"), nome));
}
query.where((Expression<Boolean>) filtro);
return em.createQuery(query).getResultList();
}
public class PerformanceConsulta {
public static void main(String[] args) {
popularBancoDeDados();
EntityManager em = JPAUtil.getEntityManager();
ProdutoDao produtoDao = new ProdutoDao(em);
produtoDao.buscaPorParametrosComCriteria("PS5", null, null);
}
private static void popularBancoDeDados() {
Categoria celulares = new Categoria("CELULARES");
Categoria videogames = new Categoria("VIDEOGAMES");
Categoria informatica = new Categoria("INFORMATICA");
Produto celular = new Produto("xiaomi","muito legal",new BigDecimal("800"), celulares);
Produto videogame = new Produto("PS5","Playstation 5",new BigDecimal("5000"), videogames);
Produto mac = new Produto("Macbook","Macbook pro retil",new BigDecimal("7000"), informatica);
Cliente cliente = new Cliente("Rodrigo", "12345");
EntityManager em = JPAUtil.getEntityManager();
ProdutoDao produtoDao = new ProdutoDao(em);
CategoriaDao categoriaDao = new CategoriaDao(em);
ClienteDao clienteDao = new ClienteDao(em);
PedidoDao pedidoDao = new PedidoDao(em);
Pedido pedido = new Pedido(cliente);
pedido.adicionarItem(new ItemPedido(10, pedido, videogame));
em.getTransaction().begin();
categoriaDao.cadastrar(celulares);
categoriaDao.cadastrar(videogames);
categoriaDao.cadastrar(informatica);
produtoDao.cadastrar(celular);
produtoDao.cadastrar(videogame);
produtoDao.cadastrar(mac);
clienteDao.cadastrar(cliente);
pedidoDao.cadastrar(pedido);
em.getTransaction().commit();
em.close();
}
}
Hibernate:
insert
into
categorias
(id, nome)
values
(null, ?)
Hibernate:
insert
into
categorias
(id, nome)
values
(null, ?)
Hibernate:
insert
into
categorias
(id, nome)
values
(null, ?)
Hibernate:
insert
into
produtos
(id, categoria_id, dataCadastro, descricao, nome, preco)
values
(null, ?, ?, ?, ?, ?)
Hibernate:
insert
into
produtos
(id, categoria_id, dataCadastro, descricao, nome, preco)
values
(null, ?, ?, ?, ?, ?)
Hibernate:
insert
into
produtos
(id, categoria_id, dataCadastro, descricao, nome, preco)
values
(null, ?, ?, ?, ?, ?)
Hibernate:
insert
into
clientes
(id, cpf, nome)
values
(null, ?, ?)
Hibernate:
insert
into
pedidos
(id, cliente_id, data, valor_total)
values
(null, ?, ?, ?)
Hibernate:
insert
into
itens_pedido
(id, pedido_id, preco_unitario, produto_id, quantidade)
values
(null, ?, ?, ?, ?)
Exception in thread "main" java.lang.ClassCastException: class org.hibernate.query.criteria.internal.predicate.CompoundPredicate cannot be cast to class java.util.function.Predicate (org.hibernate.query.criteria.internal.predicate.CompoundPredicate is in unnamed module of loader 'app'; java.util.function.Predicate is in module java.base of loader 'bootstrap')
at br.com.alura.loja.dao.ProdutoDao.buscaPorParametrosComCriteria(ProdutoDao.java:96)
at br.com.alura.loja.teste.PerformanceConsulta.main(PerformanceConsulta.java:24)