I need to compare that an entity has a date that is between two dates, unfortunately I'm not getting the results I need. Instead of comparing dates, criteria builder has created a query that compares date and time which results in no results being returned. I'm using Spring Specification to invoke criteria builder. My problem is that I'm using ZoneDateTime (I need this) to compare the dates, I'm just wondering if there's away if there's away I can convert both the dates to LocalDate so It would compare '2018-01-12' instead of '2018-01-12 09:45:00'.
Criteria Builder:
public static Specification<Activity> activityDateBetween(ZonedDateTime from, ZonedDateTime to) {
return new Specification<Activity>() {
@Override
public Predicate toPredicate(Root<Activity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate startingFrom = criteriaBuilder.greaterThanOrEqualTo(root.get(Activity_.date), from);
Predicate endingAt = criteriaBuilder.lessThanOrEqualTo(root.get(Activity_.date), to);
return criteriaBuilder.and(startingFrom, endingAt);
}
};
}
MySQL:
SELECT activity0_.id AS id1_5_,
activity0_.activity_type AS activity2_5_,
activity0_.activity_date AS activity3_5_,
activity0_.tracker_job_item_id AS tracker_5_5_,
activity0_.work_type AS work_typ4_5_,
activity0_.tracker_worker_id AS tracker_6_5_
FROM tracker_job_item_activity activity0_
WHERE activity0_.tracker_job_item_id = 71
AND ( activity0_.work_type IN ( 'BUTTONHOLING', 'SEWING', 'CUTTING' ) )
AND ( activity0_.activity_type IN ( 'RECEIVE', 'SEND' ) )
AND activity0_.activity_date >= '2018-01-12 09:29:43'
AND activity0_.activity_date <= '2018-01-12 09:29:43'
As you can see the above query is comparing date time, which is not what I want.
Alright, I've managed to get the results I want, by subtracting the time portion from ZonedDateTime. Now the search is inclusive of current date.
public static Specification<Activity> activityDateBetween(ZonedDateTime from, ZonedDateTime to) {
return new Specification<Activity>() {
@Override
public Predicate toPredicate(Root<Activity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate startingFrom = criteriaBuilder.greaterThanOrEqualTo(root.get(Activity_.date),
from.minusHours(from.getHour()).minusMinutes(from.getMinute()).minusSeconds(from.getSecond()));
Predicate endingAt = criteriaBuilder.lessThanOrEqualTo(root.get(Activity_.date), to);
return criteriaBuilder.and(startingFrom, endingAt);
}
};
}