Pregunta

What I need to get are all Events where CustomerEvent.customer.id = 123. What I actually get is exception.

Simplified entities with relevant members only:

@Table(name = "EVENT")
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 1)
public abstract class Event {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(nullable = false)
    private Integer id;
}

@Entity
@DiscriminatorValue("C")
public class CustomerEvent extends Event {
    @ManyToOne(optional = false)
    private Customer customer;
}

@Entity
@Table(name = "CUSTOMER")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(nullable = false)
    private Integer id;

}

Query:

final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Event> cq = cb.createQuery(Event.class);
final Root<Event> root = cq.from(Event.class);
cq.select(root);
cq.where(cb.equal(((Root<CustomerEvent>) root.as(CustomerEvent.class)).get(CustomerEvent_.customer).get(Customer_.id), 123));

// this predicate doesn't work either: cb.isNotNull(((Root<CustomerEvent>) root.as(CustomerEvent.class)).get(CustomerEvent_.customer));

em.createQuery(cq).getResultList(); // throws exception

Exception:

Exception [EclipseLink-6015] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.QueryException
Exception Description: Invalid query key [customer] in expression.
Query: ReadAllQuery(referenceClass=Event )
    at org.eclipse.persistence.exceptions.QueryException.invalidQueryKeyInExpression(QueryException.java:691)
¿Fue útil?

Solución

If you are using root.as(CustomerEvent.class), why not just query on CustomerEvent? Only CustomerEvent instances can have CustomerEvent.customer.id = 123 or you wouldn't need to use the 'as' function.

'As' was deprecated and JPA's Treat predicate (included in EclipseLink 2.5.1) should be used instead - the difference is that treat will exclude non-customerEvent instances within that predicate while 'as' only cast the predicate, and so was more difficult to use and not as stable. Treat allows you to safely use more complex expressions such as "Select event from Event event where (treat(event as CustomerEvent).customer.id = 123) or event.somethingelse = someotherCondition"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top