2011-07-02 39 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