2016-03-07 165 views
0

考慮一個類A是B和C.休眠條件查詢

@Table(name = "a") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class A {} 

@Table(name = "b") 
public class B extends A { 
    private String status; 
} 

@Table(name = "c") 
public class C extends A { 
    private String status; 
} 

的父現在,當我做下列標準查詢(A類):

criteria.add(Restrictions.eq("someString", status)) 

我在我的項目中有類似的設置,但生成的查詢不會產生正確的結果。 Hibernate使用表b的狀態列而不是表c(它似乎無法確定正確的)。

這是造成本地查詢的樣子:

SELECT * FROM a outer join b on a.id = b.id outer join c on a.id = c.id WHERE b.status = "someStatus" 

雖然在功能上是正確的應該是

SELECT * FROM a outer join b on a.id = b.id outer join c on a.id = c.id WHERE (b.status = "someStatus" or c.status = "someStatus") 

這是正確的,因爲只有C或B將非空,如在java中,不可能同時擁有一個既可以是b又可以是c的實體。

當對B.status進行查詢時,結果是可以的。雖然有人可能會爭辯說,使用相同的列名稱是不好的設計,或者開始討論這是一個在休眠或不休眠的問題,但我想知道是否有一些方法可以讓它更清楚地知道應該休眠哪個表應該使用。

在hibernate/criteria中有一種方法可以唯一地指定我過濾的字段在哪個子類中?

回答

0

首先,我認爲你應該在你的類「a」上擁有你的「status」屬性,這樣b和c就可以繼承相同的屬性。我可以看到您正在使用「InheritanceType.JOINED」的策略,那麼你就應該設置一個ID加入兩個表,這樣的事情:

@PrimaryKeyJoinColumn(name="ID") 

現在,你加入兩個表,但實際上它們是不同的表,那麼如果你想過濾一些特定的列,你必須指出正確的表,作爲數據庫管理員。

Criteria criteria = session.createCriteria(b.class); 
criteria.add(Restrictions.eq("someString", status)); 

我希望這些信息對您有所幫助。

祝你好運。

+0

其實它們不是同一個地位。在Java中,它們都是枚舉,不同的枚舉類型,但在數據庫中,它們被表示爲一個字符串(上面的例子被簡化了)。因此,在A中擁有狀態不是一種選擇。加入專欄和所有這一切都可以,代碼已經工作了很多年,但現在我需要搜索狀態。搜索是在類型a,所以做session.createCriteria(b.class)是不正確的。搜索是在session.createCriteria(a.class)上。作爲一種解決方法,我將實例變量status重命名爲c類中的其他內容。 – Juru