Question

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)
Was it helpful?

Solution

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"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top