2011-10-25 15 views
9

JPAでリストの@OneToMany関係のサイズを制限する方法はありますか?@OneToManyマッピングリストのサイズ制限

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST) 
private List<Comment> commentList; 

私はEclipseLinkの2.3 JPA実装を使用しています: はここに私のコードサンプルです。 ありがとうございます。ビーン検証仕様(JSR-303)の

+0

[注釈を使用するJPAではwhere句で子レコードを制限できますか?](http://stackoverflow.com/questions/5857936/using-annotations-in-jpa-can-i-limit-child -rec-with-a-where-clause) –

+0

この投稿は、保持されている要素の数を制限したいのに対し、リンクされた要素はいくつかの他の基準を持つ要素を取得したい。したがって、「正確な重複」ではありません。 – DataNucleus

答えて

12

一部は@Size(min=, max=)注釈です:

サポートされているタイプは、文字列、コレクション、地図と配列されています。注釈付き要素のサイズが最小値と最大値の間にあるかどうかを確認します。

コレクションを検証できます。

@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST) 
@Size(min=1, max=10) 
private List<Comment> commentList; 
2

あなたはJPAでこれを行うことはできませんし、マッピングが関係しているどのように多くのオブジェクトの現実を反映するように設計されているので、それは意味がありません。

パフォーマンスのためにこれを行っていますか?あなたが何ができるかを使用する場合はレイジーは、スタイルを取得し、あなたが一度取得したいどのように多くの特定にBATCHSIZEアノテーションを使用:

* 補正は:@Batchsizeは休止状態機能

です
@OneToMany(mappedBy = "publication", cascade=CascadeType.PERSIST, fetch=LAZY) 
@BatchSize(size=16) 
private List<Comment> commentList; 

あなたのコードでは、このマップされたコレクション内のどこに単に反復/ループするだけです。

どちらの方法でも、Criterias/Querysが設計されているように「ハッキング」マッピングを設計するのは効果的ではありません。@OneToManyよりも制御やパフォーマンスチューニングが必要な場合は、クエリを作成するだけです。

+0

「制限」の意味を明確にする必要がありますが、私の答えはSQL LIMITを模倣しています。サイズを検証する場合は、@ jehaの回答としてSizeアノテーションを使用します。 –

+0

これはHibernateからのバッチサイズですか? – pringlesinn

+0

私は両方を使用しているので、それらが混ざっている可能性があります。 : –

0

これを行うには、本当のortodoxの方法はありません。 私は関係を怠惰な、親オブジェクトのクエリを作成します。ワードが遅延リストを初期化せず、最初のクエリに基づいて別のクエリを実行すると、そのクエリは子テーブルで実行されます。このようにして、結合条件ではなく主基準で結果セットを制限できます。または、2番目のクエリ(子テーブルのみ)を実行し、ページネーションをサポートできます。

2

本当の問題はコレクションそのものです。 ではなく、のようにビジネスドメインをモデル化する必要があります。この解決策(@OneToManyで注釈を付けられたコレクションの)は、少数のコレクション(数十のオブジェクト)に対してのみ実行可能であり、大きなもの(数千のオブジェクト)では実行できません。すぐに制御不能になってしまうので、実際にそれらを見守る必要があります。私は現時点でAccountに関連付けられているRoleのコレクションをモデル化するためだけに使用しています。なぜなら、私のドメインには9つ以上の役割を持つアカウントがないことと、アカウントの役割が働くことが非常に重要だからですアカウントで他のすべてのm対nの関係については、私は普通の古いクエリを使用しています。

オブジェクトにコメントのコレクションを追加する代わりに、オブジェクトへの参照をCommentに明示的に追加します。クエリを使用してコメントを取得します。

特定のオブジェクト(のはArticleを使ってみましょう)のコメントを取得するためにCommentの名前付きクエリを定義します。名前のことをクエリi.c.w.を使用し、その後

@Entity 
@NamedQueries(value={ 
    @NamedQuery(name=Comment.FOR_ARTICLE, query= 
     "SELECT c FROM Comment c WHERE c.article = :article" 
    ) 
}) 
public class Comment { 
    // ... 
    @ManyToOne 
    @JoinColumn(name = "articleId") 
    private Article article; 
} 

を明示的に取得し、ページングなどを可能にするためにどのように多くの成果を制御するQuery.setMaxResultsQuery.setFirstResult

@PersistenceContext 
EntityManager em; 

Article theArticle = ...; 

Query query = em.createNamedQuery(Comment.FOR_ARTICLE, Comment.class); 
query.setParameter("article", theArticle); 
query.setFirstResult(0); 
query.setMaxResults(10); 
List<Comment> comments = (List<Comment>) query.getResultList(); 

ページングを行うには、ちょうどsetFirstResult で表示したいページに対応する最初の結果に。例えば。結果を表示するには、 setFirstResult(20)とします。