2011-07-02 26 views
6

如何编写Hibernate Criteria查询,查找超类,并检查某个子类?让我们想象一下,我们有以下的类都映射了与Hibernate,JPA:如何编写Hibernate Criteria查询,查找超类,并检查某个子类?

@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 { 
} 

当编写一个标准查询这个样子,我想,性能,使用左联接与子类:

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查询以上只是为了说明我的意思,我知道这将是更容易使用一个“正常”的加入在特定情况下, 。

回答

7

真的不清楚你想要做什么。

首先,由于Foo从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,然后用标准与富贵的根实体:

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

您将获得Foo实例,但自从Foo扩展Bar以来,这些Foo实例也是Bar实例。这就是继承。

现在,如果你动态地构建Criteria实例,并在某些时候,搜索只能返回美孚的情况下实现,你不得不使用隐含的类属性:

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

是的,我知道的SQL查询,这只是为了说明问题并澄清问题。我的查询更复杂的IRL。但是,为类属性添加限制完美地起作用。相当逻辑,当你想到它,谢谢。 – crunchdog

+0

'Restrictions.eq(“bar.class”,Foo.class))'是我正在寻找的 - 谢谢! – jlb