2011-10-13 39 views
2

是否有可能定製查詢,休眠時執行檢索給定實體的關聯?更具體地說,我想爲join子句添加一個額外的條件來迎合我正在使用的遺留數據庫中的設計缺陷。自定義加入子句休眠多對一

我面臨的問題在下面。爲表的主密鑰B包含2個字段,類別idvalue_id的。然而,在表一我只有存儲value_id並假定該類別ID是硬編碼:

@Entity 
@Table(name = "table_a") 
public class A { 
    @ManyToOne 
    @JoinColumn(name = "b_id") 
    private B b; 
} 

@Entity 
@Table(name = "table_b") 
public class B { 
    @Id 
    private int id; 
} 

當查詢A的情況下,休眠生成以下連接語句:

SELECT * 
FROM table_a a LEFT OUTER JOIN table_b b 
    ON a_.b_id = b_.value_id 

而他們詢問我需要它來執行是:

SELECT * 
FROM table_a a LEFT OUTER JOIN table_b b 
    ON a_.b_id = b_.value_id 
AND b.category_id = 2 

我知道我可以使用視圖來禾rk圍繞這個問題,但是它會要求我創建大約70個視圖,如果可能的話我想避免這些視圖。

回答

0

您可以使用此:

@OneToMany(mappedBy = "b") 
@Cascade(CascadeType.ALL) 
private List<A> aList = new ArrayList<A>(0); 

class B獲得加入和命名查詢來獲取category_id(也class B

@NamedQueries({ 
@NamedQuery(name = "B.findByCategoryId", query = "SELECT b FROM B b WHERE b.Id = :categoryId") 
}) 
+0

謝謝您的答覆。不幸的是,這個問題涉及單向關係,因此您建議的解決方案不適用。是不是可以使用JoinColumnOrFormulas?我已經嘗試使用JoinColumn的組合來指定類和JoinFormula之間的關係,以指定其他連接條件,但這隻會導致錯誤。 – gurrie

+0

也許是一個本地查詢。 –

1

我解決了這個問題。這不是最漂亮的解決方案,而是唯一的解決方案。

基本上我不得不做:

  1. 模擬一個Embbeded ID A類
  2. 使一個之間的連接 - 使用所述實際鍵列> B和類別ID比較公式

像這樣:

觀測值:我沒有測試此代碼,從我剛剛適應。

@Entity 
@Table(name = "table_a") 
public class A { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumnsOrFormulas(value={ 
     @JoinColumnOrFormula(column= 
       @JoinColumn(name="B_ID", referencedColumnName="B_ID")), 
     @JoinColumnOrFormula(formula= 
       @JoinFormula(referencedColumnName="CATEGORY_ID", 
         value = "(SELECT 2 from DUAL)"))}) //I am using Oracle 
    @JoinColumn(name = "b_id") 
    private B b; 
} 

@Entity 
@Table(name = "table_b") 
class B { 
    @Id 
    private BId id; 
} 

@Embeddable 
class BId{ 
    private int id; 
    private Integer categoryId; 
} 
+1

我想你在這裏錯過了一些東西,'BId'類是如何被使用/引用的? – Andrew

+0

@Andrew你是對的。我忘了把BId作爲B班的關鍵。我編輯了我的答案。 –