次のエンティティがあります
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> のみを受け入れるため、このコードは機能しません。
実際、私のアプローチは完全に間違っていると思いますが、現在、他の解決策は考えられません。