Search code examples
springspring-data-jpaquerydslspring-restcontroller

Multiple aliases with QuerydslBinderCustomizer


I'm using QuerydslPredicate in my RestController on an entity which has a date object, I want to be able to query for a date before/after/between given dates, hoping to have something like

  • GET /problems?createdOnAfter=XXX
  • GET /problems?createdOnBefore=YYY
  • GET /problems?createdOnAfter=XXX&createdOnBefore=YYY

My entity has the date field createdOn and I was hoping I could customise bindings for an entity path using multiple aliases i.e. adding aliases createdOnAfter & createdOnBefore - it doesn't look like I can create multiple aliases though, e.g.

@Repository
public interface ProblemRepository extends JpaRepository<Problem, String>, QueryDslPredicateExecutor<Problem>,
        QuerydslBinderCustomizer<QProblem> {

            ....

    @Override
    default void customize(QuerydslBindings bindings, QProblem root) {
        bindings.bind(root.createdOn).as("createdOnAfter").first(TemporalExpression::after);
        bindings.bind(root.createdOn).as("createdOnBefore").first(TemporalExpression::before);
    }
}

The before alias is obviously overwriting the after one.

What's the correct approach to avoid having to manually create the predicates?


Solution

  • Why not using QueryDSL Predicate ? You could do :

    @GetMapping("/problems")
    @Timed
    public ResponseEntity<List<ProblemDTO>> getAllProblems(
          @RequestParam(required = false) LocalDateTime createdOnAfter, 
          @RequestParam(required = false) LocalDateTime createdOnBefore,
          @ApiParam Pageable pageable) {
        BooleanBuilder where = new BooleanBuilder();
        if (startDate != null) {
            where = where.and(problem.createdOn.after(createdOnAfter));
        }
        if (endDate != null) {
            where = where.and(problem.createdOn.before(createdOnBefore));
        }
        Page<Donnee> page = problemRepository.findAll(where, pageable);
        return new ResponseEntity<>(problemMapper.toDTO(page.getContent())), null, HttpStatus.OK);
    }
    

    Hope it helps, Regards