2

次のエンティティがあります

class A {
  @Id
  Integer id;

  String name;

  @ElementCollection
  @JoinTable(name = "othername", joinColumns = @JoinColumn(name = "id_a"))
  @Column(name = "name")
  List<String> othernames;
}

基準 API を使用して、名前または他の名前の中置検索を使用して A のインスタンスを見つけようとしています。基本的に、この SQL クエリのようなもの:

SELECT * FROM A
    WHERE name like '%something%'
    OR id IN (SELECT id_a FROM othername WHERE name LIKE '%something%');

次のコードは、正しいことを行うためのものです。

String search = "%something%";
Subquery<Integer> subquery = c.subquery(Integer.class);
Root<A> subqueryFrom = subquery.from(A.class);
subquery.select(subqueryFrom.get(A_.id));
subquery.where(builder.like(subqueryFrom.get(A_.othernames), search));

query.where(builder.or(
    builder.like(from.get(A_.name), search),
    from.get(A_.id).in(subquery)
));

ここではサブクエリを使用しているため、結果が重複することはありません (たとえば、誰かが "a" を検索し、オブジェクトの名前に "a" が含まれ、othernames にも "a" が含まれている場合など)。

subqueryFrom.get(A.othernames) は Expression<List<String>> を返しますが、builder.like は Expression<String> のみを受け入れるため、このコードは機能しません。

実際、私のアプローチは完全に間違っていると思いますが、現在、他の解決策は考えられません。

4

1 に答える 1

0

コレクション関係を結合するには結合を使用する必要があります。get() の代わりに join() を使用します。

また、サブクエリを使用する必要はありません。代わりに、ルート クエリに結合を入れて、distinct を使用します。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#Joinを参照して ください

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#CriteriaQuery

于 2012-09-18T12:36:42.523 に答える