2014-09-08 2 views
1

Я имею следующую ошибку с запросом, где является IN, ошибка это одно:QueryException: сравнения объектов можно использовать только равные() или notEqual() операторы

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 

файлов, которые я использую следующий:

в oferta.java у меня есть это:

...............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 + " ]"; 
} 

И OfertaFacade.java метод, который я использую это один:

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; 

} 

Итак, что я делаю неправильно ?. Большое спасибо за все

ответ

0

сообщение является довольно ясно:

сравнения объектов могут использовать только операторы равны() или notEqual(). Другие сравнения должны быть сделаны с помощью клавиш запроса или прямого сравнения уровня атрибута

Таким образом, вместо того, чтобы использовать

WHERE o.negocioCif IN (:negocioCif) 

использования

WHERE o.negocioCif.id in :collectionOfIdsOfNegocios 

Вы затем сравнить атрибуты сущностей, а не сравнивая объекты, как говорится в сообщении.

+0

И в getOfertafindByLocalizacion, как я делаю выражение exp = a.get ("negocioCif")?. это будет WHERE o.negocioCif.cif в: cif – zoit

+0

Прежде всего, вы должны сгенерировать метамодель и использовать ее вместо использования строк для определения ваших полей. Это будет проще и безопаснее. Но я советую вам избежать этого ужасного критерия API. Если ваш запрос статичен, используйте JPQL. –

 Смежные вопросы

  • Нет связанных вопросов^_^