私は1対多の関係を持つ単純なエンティティを持っています
@Entity // and other @ stuff
public class Member {
@Id
private Long id;
private String name;
private List<Program> programs;
...
}
@Entity
public class Program {
@Id
private Long id;
private Long programName;
private ProgramType programType;
private Long programCost;
...
}
ここでQueryDSLを使用して、「programType = "FULLTIME"およびprogramCost> $ 1000のプログラムに登録されているすべてのメンバー」にクエリを実行したいと思います。
私は次の述語を使用しました
Predicate predicate = QMember.member.programs.any()
.programType.eq(ProgramType.FULLTIME)
.and(QMember.member.programs.any().programCost.gt(1000));
jPARepositoryを使用
memberRepository.findAll(predicate);
ここで問題となるのは、2つのクエリが独立していることです。タイプ「FULLTIME」のプログラムが少なくとも1つ、またはコストが1000を超えるプログラムが少なくとも1つあるすべてのメンバーを返します。
望ましい結果:タイプがFULLTIMEでコストが1000を超えるプログラムが少なくとも1つある場合は、メンバーを返します。
ここでいくつかの助けを得ました: https://groups.google.com/forum/#!topic/querydsl/hxdejLyqXos
基本的に、プログラムの条件は別のサブクエリにある必要があります( JPASubquery インスタンス)
QProgram program = QProgram.program
JPASubQuery subQuery = new JPASubQuery();
subQuery.from(program)
.where(program.programType.eq(ProgramType.FULLTIME),
program.programCost.gt(1000));
Predicate predicate = QMember.member.name.eq("John")
.and(subQuery.exists());
memberRepository.findAll(predicate);
@Shahbourが述べたように、これはQueryDsl 4.x +では機能しなくなりました。
私は同様のケースを持っていました(私のエンティティが双方向であることを除いて)、そして私はこれでそれを解決しました:
QProgram program = QProgram.program;
QProgram member = QProgram.member;
Predicate predicate = JPAExpressions
.selectOne()
.from(program)
.where(program.member.id.eq(member.id),
program.programCost.gt(1000),
program.programType.eq(ProgramType.FULLTIME))
)
.exists();
memberRepository.findAll(predicate);