【发布时间】:2010-09-28 13:06:20
【问题描述】:
假设我有以下实体域:
@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 Criteria 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));
我在“join”中得到 NPE,因为属性“details”不属于 Entity1(这实际上是真的,我必须在 Entity2.class 上进行选择)。问题是,当我必须使用 Criteria API 构建动态查询时,我对层次结构一无所知,我只是传递了一个类。
我知道 Criteria API 是类型安全的,但有没有办法解决这个问题?可能带有别名(就像我之前使用 Hibernate Criteria API,遍历带有别名的连接):
Criteria c = session.createCriteria(Entity1.class);
c.createAlias("details", "d");
c.add(Restrictions.ge("d.quantity", 1));
【问题讨论】:
-
其实我有点错了。它是 JPA2 的休眠实现,允许您运行我上面提到的 JPQL 查询。如果您使用 OpenJPA(例如),这两种情况都会失败。
标签: jpa-2.0