我尝试使用ParameterExpression
执行动态查询,但获得异常。
我的方法:
public List<Atividade> buscarAtividades(Armario armario) {
CriteriaBuilder builder = manager.getCriteriaBuilder();
CriteriaQuery<Atividade> criteriaQuery = builder.createQuery(Atividade.class);
Root<Atividade> atividade = criteriaQuery.from(Atividade.class);
criteriaQuery.select(atividade);
criteriaQuery.distinct(true);
List<Predicate> predicates = new ArrayList<Predicate>();
if(armario != null){
ParameterExpression<Armario> ard = builder.parameter(Armario.class, "ard");
predicates.add(builder.equal(atividade.get("armario").get("numero"), ard));
}
criteriaQuery.where(predicates.toArray(new Predicate[0]));
TypedQuery<Atividade> query = manager.createQuery(criteriaQuery);
return query.getResultList();
}
当我执行查询时,我会收到堆栈:
fev 02, 2017 11:31:49 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
ADVERTÊNCIA: #{cadastroAtividadeBean.buscarAtividades}: org.hibernate.QueryException: Named parameter [ard] not set
javax.faces.FacesException: #{cadastroAtividadeBean.buscarAtividades}: org.hibernate.QueryException: Named parameter [ard] not set
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.faces.el.EvaluationException: org.hibernate.QueryException: Named parameter [ard] not set
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 28 more
Caused by: org.hibernate.QueryException: Named parameter [ard] not set
at org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:234)
at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1307)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1396)
at org.hibernate.Query.getResultList(Query.java:417)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72)
at com.vivo.tecnico.repository.AtividadesRepository.buscarAtividades(AtividadesRepository.java:49)
at com.vivo.tecnico.controller.CadastroAtividadeBean.buscarAtividades(CadastroAtividadeBean.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:247)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 29 more
fev 02, 2017 11:31:49 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
GRAVE: javax.faces.el.EvaluationException: org.hibernate.QueryException: Named parameter [ard] not set
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.QueryException: Named parameter [ard] not set
at org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:234)
at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1307)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1396)
at org.hibernate.Query.getResultList(Query.java:417)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72)
at com.vivo.tecnico.repository.AtividadesRepository.buscarAtividades(AtividadesRepository.java:49)
at com.vivo.tecnico.controller.CadastroAtividadeBean.buscarAtividades(CadastroAtividadeBean.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:247)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 29 more
知道哪里可能有问题?
我找了很多关于但总是堆叠的帖子。
Armario.class
package com.vivo.tecnico.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Armario {
private Long id;
private String numero;
private String endereco;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Armario other = (Armario) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
Atividade.class
package com.vivo.tecnico.model;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class Atividade {
private Long id;
private String numero;
private String cidade;
private Armario armario;
private Date dataAtividade;
private Date dataEncerramento;
private String endereco;
private Funcionario funcionario;
private Causa causa;
private Segmento segmento;
private Status status;
private String observacao;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "armario")
public Armario getArmario() {
return armario;
}
public void setArmario(Armario armario) {
this.armario = armario;
}
@Temporal(TemporalType.DATE)
@Column(name = "data_atividade")
public Date getDataAtividade() {
return dataAtividade;
}
public void setDataAtividade(Date dataAtividade) {
this.dataAtividade = dataAtividade;
}
@Temporal(TemporalType.DATE)
@Column(name = "data_encerramento")
public Date getDataEncerramento() {
return dataEncerramento;
}
public void setDataEncerramento(Date dataEncerramento) {
this.dataEncerramento = dataEncerramento;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "funcionario_id")
public Funcionario getFuncionario() {
return funcionario;
}
public void setFuncionario(Funcionario funcionario) {
this.funcionario = funcionario;
}
@Enumerated(EnumType.STRING)
public Causa getCausa() {
return causa;
}
public void setCausa(Causa causa) {
this.causa = causa;
}
@Enumerated(EnumType.STRING)
public Segmento getSegmento() {
return segmento;
}
public void setSegmento(Segmento segmento) {
this.segmento = segmento;
}
@Enumerated(EnumType.STRING)
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getObservacao() {
return observacao;
}
public void setObservacao(String observacao) {
this.observacao = observacao;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Atividade other = (Atividade) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
答案 0 :(得分:1)
您可以像这样使用ParameterExpression: 假设您有一些输入过滤器,例如:
1) inizialize predicateList(用于where子句)和paramList(用于param)
Map<ParameterExpression,String> paramList = new HashMap();
List<Predicate> predicateList = new ArrayList<>();
2 )检查输入是否为null并创建predicateList和param
if( input.getFilterCF() != null){
//create ParameterExpression
ParameterExpression<String> cf = cb.parameter(String.class);
//if like clause
predicateList.add(cb.like(root.<String>get("cf"), cf));
paramList.put(cf , input.getFilterCF() + "%");
//if equals clause
//predicateList.add(cb.equal(root.get("cf"), cf));
//paramList.put(cf,input.getFilterCF()());
}
3 )创建where子句
cq.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])));
TypedQuery<Tuple> q = _em.createQuery(cq);
4 )设置参数值
for(Map.Entry<ParameterExpression,String> entry : paramList.entrySet())
{
q.setParameter(entry.getKey(), entry.getValue());
}
答案 1 :(得分:0)
在条件查询(builder.parameter(Armario.class, "ard")
中创建名称为ard
的参数)中定义参数时,您需要设置运行时要使用的参数值。
在你的情况下,这意味着
query.setParameter("ard", someValue);
在致电query.getResultList()
之前。
答案 2 :(得分:0)
您必须加入关联实体才能访问其字段以进行操作,例如添加过滤器或级联连接。此外,如果要向查询添加参数,请在执行参数之前设置该参数。
CriteriaBuilder builder = manager.getCriteriaBuilder();
CriteriaQuery<Atividade> criteriaQuery = builder.createQuery(c.class);
Root<Atividade> atividade = criteriaQuery.from(Atividade.class);
criteriaQuery.select(atividade);
criteriaQuery.distinct(true);
Join<Atividade, Armario> armarioJoin = atividade.join("armario", JoinType.INNER)
List<Predicate> predicates = new ArrayList<Predicate>();
if(armario != null){
ParameterExpression<Armario> ard = builder.parameter(String.class, "ard");
predicates.add(builder.equal(armarioJoin.get("numero"), ard));
}
criteriaQuery.where(predicates.toArray(new Predicate[0]));
TypedQuery<Atividade> query = manager.createQuery(criteriaQuery);
query.setParameter("ard", armario.getNumero());
return query.getResultList()