QueryException: Object comparisons can only use the equal() or notEqual() operators

不想你离开。 提交于 2019-12-22 12:27:55

问题


I have the next mistake with a Query where is an IN, the mistake is this one:

 Caused by: Exception [EclipseLink-6075] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.QueryException
 Exception Description: Object comparisons can only use the equal() or notEqual() operators.  Other comparisons must be done through query keys or direct attribute level comparisons. 
 Expression: [
 Relation operator [ IN ]
 Query Key negocioCif
  Base com.agrupadosobligatorio.persistencia.Oferta
 Constant [com.agrupadosobligatorio.bean.Negocio[ cif=12345678 ], com.agrupadosobligatorio.bean.Negocio[ cif=administrador ]]]
Query: ReadAllQuery(referenceClass=Oferta )
at org.eclipse.persistence.exceptions.QueryException.invalidOperatorForObjectComparison   (QueryException.java:636)
at org.eclipse.persistence.internal.expressions.RelationExpression.normalize(RelationExpression.java:527)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.normalize(SQLSelectStatement.java:1300)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildNormalSelectStatement(ExpressionQueryMechanism.java:516)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1602)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:705)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:642)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:598)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:839)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:560)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:797)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1056)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:390)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1144)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2863)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1501)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1483)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1457)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:485)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
at com.agrupadosobligatorio.persistencia.OfertaFacade.getOfertafindByLocalizacion(OfertaFacade.java:114)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5366)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
at sun.reflect.GeneratedMethodAccessor122.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5338)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5326)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
... 45 more

The files I use are the next one:

In oferta.java I have this:

 ...............More NamedQuery...........
     @NamedQuery(name = "Oferta.findByLocalizacion", query = "SELECT o FROM Oferta o WHERE o.negocioCif IN (:negocioCif)"),  
  .............More namedQuery
 public class Oferta implements Serializable {
  private static final long serialVersionUID = 1L;
 @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idoferta")
private Integer idoferta;
@Basic(optional = false)
@NotNull
@Column(name = "fecha_inicio")
@Temporal(TemporalType.TIMESTAMP)
private Date fechaInicio;
@Basic(optional = false)
@NotNull
@Column(name = "fecha_fin")
@Temporal(TemporalType.TIMESTAMP)
private Date fechaFin;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 150)
@Column(name = "descripcion")
private String descripcion;
// @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Basic(optional = false)
@NotNull
@Column(name = "precio_inicial")
private BigDecimal precioInicial;
@Basic(optional = false)
@NotNull
@Column(name = "precio_final")
private BigDecimal precioFinal;
@JoinColumn(name = "negocio_cif", referencedColumnName = "cif")
@ManyToOne(optional = false)
private Negocio negocioCif;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "ofertaIdoferta")
private Collection<Cupon> cuponCollection;

public Oferta() {
}

public Oferta(Integer idoferta) {
    this.idoferta = idoferta;
}

public Oferta(Integer idoferta, Date fechaInicio, Date fechaFin, String descripcion, BigDecimal precioInicial, BigDecimal precioFinal) {
    this.idoferta = idoferta;
    this.fechaInicio = fechaInicio;
    this.fechaFin = fechaFin;
    this.descripcion = descripcion;
    this.precioInicial = precioInicial;
    this.precioFinal = precioFinal;
}

public Integer getIdoferta() {
    return idoferta;
}

public void setIdoferta(Integer idoferta) {
    this.idoferta = idoferta;
}

public Date getFechaInicio() {
    return fechaInicio;
}

public void setFechaInicio(Date fechaInicio) {
    this.fechaInicio = fechaInicio;
}

public Date getFechaFin() {
    return fechaFin;
}

public void setFechaFin(Date fechaFin) {
    this.fechaFin = fechaFin;
}

public String getDescripcion() {
    return descripcion;
}

public void setDescripcion(String descripcion) {
    this.descripcion = descripcion;
}

public BigDecimal getPrecioInicial() {
    return precioInicial;
}

public void setPrecioInicial(BigDecimal precioInicial) {
    this.precioInicial = precioInicial;
}

public BigDecimal getPrecioFinal() {
    return precioFinal;
}

public void setPrecioFinal(BigDecimal precioFinal) {
    this.precioFinal = precioFinal;
}

public Negocio getNegocioCif() {
    return negocioCif;
}

public void setNegocioCif(Negocio negocioCif) {
    this.negocioCif = negocioCif;
}

@XmlTransient
public Collection<Cupon> getCuponCollection() {
    return cuponCollection;
}

public void setCuponCollection(Collection<Cupon> cuponCollection) {
    this.cuponCollection = cuponCollection;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (idoferta != null ? idoferta.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Oferta)) {
        return false;
    }
    Oferta other = (Oferta) object;
    if ((this.idoferta == null && other.idoferta != null) || (this.idoferta != null && !this.idoferta.equals(other.idoferta))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "com.agrupadosobligatorio.bean.Oferta[ idoferta=" + idoferta + " ]";
}

And in OfertaFacade.java the method which I use is this one:

   public List<Oferta> getOfertafindByLocalizacion(String direccion){
     CriteriaBuilder cBuilder2 = em.getCriteriaBuilder();
    CriteriaQuery<Negocio> cQuery2 =cBuilder2.createQuery(Negocio.class);
    Root<Negocio> b = cQuery2.from(Negocio.class);

    ParameterExpression <String> param2 = cBuilder2.parameter(String.class);
    String direccion2="%"+direccion;
    cQuery2.select(b).where(cBuilder2.like(cBuilder2.lower(b.get("direccion").as(String.class)),"%"+direccion+"%"));
    TypedQuery<Negocio> tQuery2 = em.createQuery(cQuery2);
    List<Negocio> negocio = tQuery2.getResultList();



    CriteriaBuilder cBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Oferta> cQuery =cBuilder.createQuery(Oferta.class);
    Root<Oferta> a = cQuery.from(Oferta.class);
    ParameterExpression <String> param = cBuilder.parameter(String.class);


    Expression<String> exp = a.get("negocioCif");
    Predicate predicate = exp.in(negocio);
    //Predicate = exp.
    cQuery.select(a).where(predicate);

    //cQuery.select(a).where(cBuilder.in((a.get("negocio").in(negocio)));
    TypedQuery<Oferta> tQuery = em.createQuery(cQuery);
    List<Oferta> oferta = tQuery.getResultList();
    return oferta;

}

So, what I'm doing wrong?. Thanks so much for everything


回答1:


The message is quite clear:

Object comparisons can only use the equal() or notEqual() operators. Other comparisons must be done through query keys or direct attribute level comparisons

So, instead of using

WHERE o.negocioCif IN (:negocioCif)

use

WHERE o.negocioCif.id in :collectionOfIdsOfNegocios

You'll then compare attributes of the entities rather than comparing entities, as the message tells you to do.



来源:https://stackoverflow.com/questions/25719104/queryexception-object-comparisons-can-only-use-the-equal-or-notequal-operat

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!