che sto cercando di realizzare qualcosa di simile a quanto segue, utilizzando l'APP Criteri API:Come fare riferimento ad un campo specifico di sottoclasse in una CriteriaQuery in cui viene interrogata la super classe?
SELECT b FROM Box b JOIN SpecialItem s WHERE s.specialAttr = :specialAttr
Gli oggetti sono
Box
@Entity
public class Box implements Serializable {
...
@ManyToOne
@JoinColumn(name = "item_id")
Item item;
...
}
Articolo
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item implements Serializable {
@Id
private String id;
...
}
SpecialItem
@Entity
public class SpecialItem extends Item {
private String specialAttr;
...
}
Il mio tentativo
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(Box.class);
Root from = cq.from(Box.class);
// Nothing to specify SpecialItem over Item!
Join join = from.join("item", JoinType.LEFT);
// java.lang.IllegalArgumentException: Unable to
// resolve attribute [specialAttr] against path [null]
Path p = join.get("specialAttr");
Predicate predicate = cb.equal(p, "specialValue");
cq.where(predicate);
Non sorprende che viene generata un'eccezione perché specialAttr non è un membro della classe Item.
Come posso restituire tutti gli Box
es che contengono uno SpecialItem
, dove lo SpecialItem.specialAttr
ha qualche valore?
Grazie, ma come farei utilizzando l'API Criteri? – Alex
Grazie mille! Fuori se interesse, è una soluzione possibile con JPA 2.0? – Alex
Sì, ma in un modo approssimativo che potrebbe causare ulteriori join. Dovresti essere esplicito nei tuoi join e costruire la query al contrario. Qualcosa come "seleziona b da Box b, SpecialtyItem si dove b.item = si e si.specialAttr =: specialAttr" – Chris