如何为超类编写Hibernate Criteria查询,并检查某个子类?

如何为超类编写Hibernate Criteria查询,并检查某个子类? 让我们假设我们有以下所有使用Hibernate-JPA映射的类:

@Entity @Inheritance(strategy = InheritanceType.JOINED) public class Bar { @Id @Column(name = "id") private Long id; } @Entity @PrimaryKeyJoinColumn(name="bar_id") public class Foo extends Bar { } @Entity @PrimaryKeyJoinColumn(name="bar_id") public class Goo extends Bar { } 

在编写像这样的Criteria查询时,为了提高性能,我希望对子类使用左连接:

 getSession() .createCriteria(Bar.class) .createAlias("Foo", "foo", CriteriaSpecification.LEFT_JOIN) .add(Restrictions.isNotNull("foo.bar_id")) .list(); 

这失败了,因为关联路径“Foo”显然不起作用,但它会说明我想要的。 或者是否有另一种方法来执行此类查询? 我需要在超类上执行查询。 如果我在SQL中完成它,它将如下所示:

 select b.* from bar b left join foo f on f.bar_id = b.id where f.bar_id is not null; 

上面的SQL查询只是为了说明我的意思,我知道在特定情况下使用“普通”连接会更容易。

目前还不清楚你想做什么。

首先,由于Fooinheritance自Bar,因此搜索Bar实例将自动返回Foo实例。 Hibernate自己负责连接表。

第二:你的SQL查询真的很奇怪。 你正在做一个左连接(这意味着你正在搜索可能没有关联foo的栏),但你也有一个关闭foo.bar_id的地方非空。 这实际上构成了一个内连接,可以重写为

 select b.* from bar b inner join foo f on f.bar_id = b.id 

如果你想要做的只是搜索Foos和Foos,那么使用Criteria with Foo作为root实体:

 getSession() .createCriteria(Foo.class) .list(); 

您将获得Foo实例,但由于Foo扩展了Bar,因此这些Foo实例也是Bar实例。 这就是inheritance。

现在,如果您正在动态构建Criteria实例,并且在某些时候意识到搜索必须只返回Foo的实例,则必须使用隐式类属性:

 Criteria c = getSession().createCriteria(Bar.class, "bar") // ... if (limitToFoos) { c.add(Restrictions.eq("bar.class", Foo.class)); }