假設我有以下實體域:JPA2條件查詢在實體層次
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE")
public abstract class Entity1 {
//some attributes
}
@Entity
@DiscriminatorValue("T1")
public class Entity2 extends Entity1 {
@OneToMany(fetch=FetchType.EAGER, cascade = { CascadeType.ALL }, mappedBy="parent")
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<Entity1Detail> details = new HashSet<Entity1Detail>();
}
@Entity
public class Entity1Detail {
@ManyToOne
@JoinColumn(name="REF")
private Entity2 parent;
@Basic
private Integer quantity;
}
@Entity
@DiscriminatorValue("T2")
public class Entity3 extends Entity1 {
//some other attributes
}
當我做了JPQL查詢:
select e from Entity1 e left join e.details d where d.quantity > 1
運行狀況良好(左連接; P)。然而,當我嘗試使用JPA2標準API來構建相同的查詢:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery q = builder.createQuery();
Root r = q.from(Entity1.class);
q.select(r);
q.where(builder.gt(r.join("details", JoinType.LEFT).get("quantity"), 1));
我的「加盟」,因爲屬性的「詳細信息」不屬於ENTITY1(實際上是真正得到NPE,我必須選擇在Entity2.class上)。事情是,當我必須使用Criteria API構建我的動態查詢時,我並不真正瞭解層次結構的任何內容,只是傳遞了一個Class。
我明白,Criteria API是類型安全的,所有這一切,但有沒有辦法解決這個問題?有可能別名(爲我所用的Hibernate API的標準之前,穿越與別名連接):
Criteria c = session.createCriteria(Entity1.class);
c.createAlias("details", "d");
c.add(Restrictions.ge("d.quantity", 1));
實際上,我有點不對。它是JPA2的hibernate實現,允許您運行上面提到的JPQL查詢。如果您使用OpenJPA(例如),則在兩種情況下都會失敗。 – 2010-10-13 15:42:38