Olá, gostaria da ajudar de alguém pois já procurei por uma solução e não tive muito sucesso, mesmo olhando a documentação.
A idéia é fazer método abaixo com(JPQL) utilizando Criteria do JPA.
public List<Produto> filter(ProdutoRastreavelModelFilter p) {
return entityManager.createQuery("select distinct(p) from Produto p join fetch p.rastreabilidade r where r.pedido = :pedido", Produto.class)
.setParameter("pedido", p.getNumeroPedido())
.getResultList();
}
Entity Produto
@Entity
@Table(name = "produto")
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String codigo;
private String lote;
private String origem;
private YearMonth validade;
private String descricao;
@ManyToMany(mappedBy = "produtos")
private List<Rastreabilidade> rastreabilidade = new ArrayList<>();
}
Entity Rastreabilidade
@Entity
@Table(name = "rastreabilidade")
public class Rastreabilidade implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String pedido;
private LocalDate dataSeparacao;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "rastreabilidade_produto", joinColumns = {
@JoinColumn(name = "rastreabilidade_id") },
inverseJoinColumns = {
@JoinColumn(name = "produto_id") })
private List<Produto> produtos = new ArrayList<>();
}
Método com Criteria
public List<Produto> filter(ProdutoRastreavelModelFilter p) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Produto> criteria = builder.createQuery(Produto.class);
Root<Produto> root = criteria.from(Produto.class);
root.fetch(Produto_.rastreabilidade);
criteria.distinct(true);
Predicate[] predicates = criaRestricoes(p, builder, root);
criteria.where(predicates);
TypedQuery<Produto> query = entityManager.createQuery(criteria);
return query.getResultList();
}
Método com os predicates
private Predicate[] criaRestricoes(ProdutoRastreavelModelFilter p, CriteriaBuilder builder, Root<Produto> root) {
List<Predicate> predicates = new ArrayList<>();
if (p.getNumeroPedido() != null) {
predicates.add(builder.equal(root.get("rastreabilidade").get("pedido"), p.getNumeroPedido()));
}
return predicates.toArray(new Predicate[predicates.size()]);
}
Exceção
Caused by: java.lang.IllegalStateException: Illegal attempt to dereference path source [null.rastreabilidade] of basic type
at org.hibernate@5.3.9.Final//org.hibernate.query.criteria.internal.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:82)
at org.hibernate@5.3.9.Final//org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:174)
at deployment.er7system.war//com.carloser7.er7system.dao.RastreabilidadeDAO.criaRestricoes(RastreabilidadeDAO.java:80)
at deployment.er7system.war//com.carloser7.er7system.dao.RastreabilidadeDAO.filter(RastreabilidadeDAO.java:68)
at deployment.er7system.war//com.carloser7.er7system.bean.RastreabilidadeBean.filter(RastreabilidadeBean.java:108)
at deployment.er7system.war//com.carloser7.er7system.bean.RastreabilidadeBean$Proxy$_$$_WeldSubclass.filter(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.glassfish.javax.el@3.0.1-b08-jbossorg-1//com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
at org.glassfish.javax.el@3.0.1-b08-jbossorg-1//com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at org.glassfish.javax.el@3.0.1-b08-jbossorg-1//com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.core@3.1.0.Final//org.jboss.weld.module.web.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.core@3.1.0.Final//org.jboss.weld.module.web.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at org.jboss.weld.core@3.1.0.Final//org.jboss.weld.module.web.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.core@3.1.0.Final//org.jboss.weld.module.web.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.jsf-impl@2.3.9.SP01//com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:65)
at com.sun.jsf-impl@2.3.9.SP01//com.sun.faces.application.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:66)