JPA Criteria使用单表inheritance查询实体层次结构

说我有以下实体:

@Entity @Inheritance(strategy = SINGLE_TABLE) @DiscriminatorColumn(name = "type") public abstract class BaseEntity { private Date someDate; private Date otherDate; private boolean flag; } @Entity @DiscriminatorValue("entity1") public class Entity1 extends BaseEntity { private String someProperty; } @Entity @DiscriminatorValue("entity2") public class Entity2 extends BaseEntity { private String otherProperty; } 

我正在尝试构建一个条件查询,该查询根据BaseEntity和两个子类中的属性返回BaseEntity实例。 所以基本上我正在寻找与这个伪SQL相对应的标准查询:

 SELECT * FROM  WHERE someDate  ? AND flag = ? AND someProperty = ? AND otherProperty = ?; 

我不想构建两个单独的查询,因为它们有很多重叠(即大多数属性都在基类中)。 但是,如果我将BaseEntity声明为root,我还没有想出一种在查询中引用子类属性的方法。 是否可以构建这样的标准查询?

更新:

也许一些代码会澄清这个问题。 我基本上喜欢做这样的事情:

 CriteriaBuilder builder = ...; CriteriaQuery query = ...; Root root = ...; query.select(root).where(builder.and( builder.lessThan(root.get(BaseEntity_.someDate), new Date()), builder.greaterThan(root.get(BaseEntity_.otherDate), new Date()), builder.isTrue(root.get(BaseEntity_.flag)), builder.equal(root.get(Entity1_.someProperty), "foo"), <-- This won't work builder.equal(root.get(Entity2_.otherProperty), "bar") <-- Neither will this )); 

现在,我理解为什么上面的代码示例不起作用,但我想知道是否有办法解决它。

我设法通过将BaseEntity根目录转换为与CriteriaBuilder.treat()对应的子类类型的新根来解决这个问题,如下所示:

 CriteriaBuilder builder = ...; CriteriaQuery query = ...; Root root = ...; Root entity1 = builder.treat(root, Entity1.class); Root entity2 = builder.treat(root, Entity2.class); query.select(root).where(builder.and( builder.lessThan(root.get(BaseEntity_.someDate), new Date()), builder.greaterThan(root.get(BaseEntity_.otherDate), new Date()), builder.isTrue(root.get(BaseEntity_.flag)), builder.equal(entity1.get(Entity1_.someProperty), "foo"), builder.equal(entity2.get(Entity2_.otherProperty), "bar") )); 

尝试Junction 。 你总是可以这样做:

 Criteria crit = session.createCriteria(YourClassName.class); Criterion cr1 = Restrictions.lt("propertyname", propertyvalue); Criterion cr2 = Restrictions.gt("propertyname", propertyvalue); Criterion cr3 = Restrictions.eq("propertyname", propertyvalue); Criterion cr4 = Restrictions.eq("propertyname", propertyvalue); Junction cond = Restrictions.conjunction(); cond.add(cr1).add(cr2).add(cr3).add(cr4) crit.add(cond); 

我希望我能正确地得到你的问题。