Предикат QueryDSL SetPath.любой с несколькими условиями

у меня есть простой объект с отношением один ко многим

@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 =" полный рабочий день "и programCost > $ 1000'

я использовал следующий предикат

Predicate predicate = QMember.member.programs.any()
    .programType.eq(ProgramType.FULLTIME)
      .and(QMember.member.programs.any().programCost.gt(1000));

С JPARepository

memberRepository.findAll(predicate);

Теперь проблема в том, что два запроса являются независимыми. Он возвращает членов al по крайней мере с одной программой типа "FULLTIME" или по крайней мере одной программой стоимость больше 1000.

желаемый результат: возврат участников, если у него есть хотя бы одна программа, которая имеет тип FULLTIME и стоимость > 1000.

2 ответов


тут помочь : https://groups.google.com/forum/#!тема/querydsl/hxdejLyqXos

в основном условия программы должны быть в отдельном подзапросе (a 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.икс.+

У меня был подобный случай (за исключением того, что моего лица bidirectionnal), и я решил ее так :

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);