2011-08-02 107 views
17

我在兩個表之間有父/子關係,並且在我的Java類中有相應的映射。這些表粗略看起來像:註釋過濾@OneToMany關聯的結果

A (ref number, stuff varchar2(4000)) 
B (a_ref number, other number, foo varchar2(200)) 

和Java代碼:

@Entity 
class A { 
    @Id 
    @Column(name = "REF") 
    private int ref; 

    @OneToMany 
    @JoinColumn(name = "A_REF", referencedName = "REF") 
    private Set<B> bs; 
} 

@Entity 
class B { 
    @Id 
    @Column(name = "A_REF") 
    private int aRef; 

    @Id 
    @Column(name = "OTHER") 
    private int other; 
} 

這工作得很好,但我想上,我從子表檢索行添加過濾器。所生成的查詢如下:

select a_ref, other, foo from B where a_ref = ? 

而且我想它是:

select a_ref, other, foo from B where a_ref = ? and other = 123 

額外的過濾器將只有一個列名和一個硬編碼值。有沒有辦法做到這一點使用hibernate註釋?

我看過@JoinFormula,但是我總是需要引用父表中的列名(在JoinFormula的name屬性中)。

在此先感謝您的任何建議。

+0

好奇,爲什麼不把它作爲參數傳入呢? '哪裏a_ref =?和其他=?'。傳入的值可以硬編碼,如果這是你需要做的(我會建議使用可配置的屬性系統)。 – ADTC

回答

26

它不受JPA支持,但如果您使用休眠作爲JPA提供程序,那麼您可以使用註釋@FilterDef@Filter

Hibernate Core Reference Documentation

Hibernate3的具有預先定義的過濾標準和在兩個一類電平或者集合連接 這些濾波器的能力。過濾器 條件允許您定義類似於 類中現有的「where」屬性和各種收集元素的限制條款。但是,這些過濾條件可以參數化爲 。然後應用程序可以在運行時決定是否啓用某些過濾器,以及它們的參數值 應該是什麼。過濾器可以像數據庫視圖一樣使用,但它們是在應用程序內參數化的 。

爲例

@Entity 
public class A implements Serializable{ 
    @Id 
    @Column(name = "REF") 
    private int ref; 

    @OneToMany 
    @JoinColumn(name = "A_REF", referencedColumnName = "REF") 
    @Filter(name="test") 
    private Set<B> bs; 
} 

@Entity 
@FilterDef(name="test", defaultCondition="other = 123") 
public class B implements Serializable{ 
    @Id 
    @Column(name = "A_REF") 
    private int aRef; 

    @Id 
    @Column(name = "OTHER") 
    private int other; 
} 

Session session = entityManager.unwrap(Session.class); 
session.enableFilter("test"); 
A a = entityManager.find(A.class, new Integer(0)) 
a.getb().size() //Only contains b that are equals to 123 
+0

謝謝,它運作良好。雖然你必須動態地啓用它(我會始終啓用它),但有點煩人。我會和它一起生活! – Xavier

+0

entityManager上沒有upwrap方法:( –

+1

對不起,它只能在JPA 2.0以後纔可用。http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#unwrap(java.lang。類) –

0

與JPA 1,您可以使用所提供的解決方案,但變化不折到getDelegate是那樣的

Session session = (Session)entityManager.getDelegate(); 

,它去上班。

0

如果我理解正確的問題,還有一個辦法用javax.persistence註釋來做到這一點(我在多對一使用這個自己,並從定製的here的答案):

@JoinColumns({ 
    @JoinColumn(name = "A_REF", referencedColumnName = "REF"), 
    @JoinColumn(name = "B_TABLE_NAME.OTHER", referencedColumnName = "'123'")}) 
@OneToMany 
private Set<B> bs; 

注意single引用列中的引號,這是您正在查找的值。

更多信息here