23

2 つのテーブル間に親子関係があり、Java クラスに対応するマッピングがあります。表は大まかに次のようになります。

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

追加のフィルターは、列名とハードコーディングされた値のみです。休止状態の注釈を使用してそれを行う方法はありますか?

を見てきましたが@JoinFormula、常に親テーブルの列名を参照する必要があります ( nameJoinFormula の属性で)。

アドバイスをよろしくお願いします。

4

4 に答える 4

32

JPA ではサポートされていませんが、JPA プロバイダーとして hibernate を使用している場合は、アノテーション@FilterDef@Filter.

Hibernate Core リファレンス ドキュメント

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
于 2011-08-03T01:56:16.667 に答える
2

JPA 1では、提供されたソリューションを使用できますが、unwrapをgetDelegateに変更してそのようにすることができます

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

そしてそれはうまくいくでしょう。

于 2015-02-26T11:25:52.747 に答える
1

質問を正しく理解している場合は、javax.persistence アノテーションを使用してこれを行う方法があります (私はこれを ManyToOne で自分で使用し、ここから回答を調整しました)。

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

referencedColumnName の一重引用符に注意してください。これが探している値です。

詳細はこちら

于 2016-10-14T07:35:27.837 に答える