I want to create a Search specification where I can select data based on Date range. I tried this:
@Getter
@Setter
public class BillingSummarySearchParams {
private LocalDateTime startDate;
private LocalDateTime endDate;
}
Search Specification
public List<BillingSummaryFullDTO> findBillingInvoicesSummary(BillingSummarySearchParams params)
{
Specification<BillingSummary> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getStartDate() != null | params.getEndDate() != null) {
predicates.add(cb.like(cb.lower(root.get("startDate")), "%" + params.getStartDate() + "%"));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return billingSummaryService.findAll(spec).stream().map(billingSummaryMapper::toFullDTO).collect(Collectors.toList());
}
Search SQL
public List<BillingSummary> findAll(Specification<BillingSummary> spec)
{
String hql = "select e from " + BillingSummary.class.getName() + " e where e.createdAt BETWEEN :startDate AND :endDate ORDER BY e.createdAt DESC";
TypedQuery<BillingSummary> query = entityManager.createQuery(hql, BillingSummary.class).setParameter("startDate", spec).setParameter("endDate", spec);
List<BillingSummary> list = query.getResultList();
return list;
}
It's not clear to me how I can build the specification with 2 dates to work and with only one.
What is the proper way to get the dates from the spec object?