Reputation: 703
Let say I have a column in Oracle DB like this:
SOMETHING_TS TIMESTAMP WITH TIME ZONE
And I would like to use CriteriaQuery to filter by this column.
I can used native query to achieve this:
SELECT *
FROM SOMETHING
WHERE TRUNC(SOMETHING_TS) = TO_DATE('2016-12-08','YYYY-MM-DD');
But in Java I have failed to do so, below is my sample code:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Date date = new Date();
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", Date.class, cb.parameter(Date.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
TypedQuery<MyClass> query = em.createQuery(cq);
query.setParameter("somethingDt", date);
Upvotes: 5
Views: 25272
Reputation: 11
A simple solution that worked for me. I create a Calendar variable setting the day I want to compare. But I truncated the date to consider until days and discosidering hours, minutes and seconds.
So the idea is trunc using Calendar to prevent using CriteriaBuilder.function().
List<Predicate> predicates = new ArrayList<>();
Join<A, B> joinB = a.join("B");
Calendar startOfTheCurrentDay = GregorianCalendar.from(
ZonedDateTime.ofInstant(Instant.now().truncatedTo(ChronoUnit.DAYS), ZoneId.systemDefault()));
predicates.add(
criteriaBuilder.lessThanOrEqualTo(
criteriaBuilder.literal(startOfTheCurrentDay),
joinB.<Calendar>get("expirationDate")
)
);
Upvotes: 0
Reputation: 1728
Javatar's answer even if works is not perfect since to_date returns Date and not String. Also there is not much point to use a parameter, better use a literal. Here is my answer which would work for anyone.
predicates.add(criteriaBuilder.lessThanOrEqualTo(criteriaBuilder.function("TRUNC", java.sql.Date.class, root.get("executionDateTime")),
criteriaBuilder.function("TO_DATE", java.sql.Date.class, criteriaBuilder.literal(request.getExecutionToDate().toString()),
criteriaBuilder.literal("yyyy-mm-dd"))));
Upvotes: 0
Reputation: 899
Javatar's answer didn't solve my specific case but here is what helped me in case it helps anyone.
private List<MyClass> selectMyClassByDate(Date date) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Root<MyClass> myClass = cq.from(MyClass.class);
cq.select(myClass);
cq.where(cb.equal(cb.function("date", Date.class,
myClass.get(MyClass_.timestamp)), date));
final TypedQuery<MyClass> tq = em.createQuery(cq);
log.fine(
tq.unwrap(org.apache.openjpa.persistence.QueryImpl.class)
.getQueryString());
List<MyClass> myClassList = tq.getResultList();
return myClassList;
}
sorry this only applies to MYSQL
Upvotes: 2
Reputation: 703
Seems like I have found my answer:
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", String.class, cb.parameter(String.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
Then when I set parameter, I will set the String format of date to query.
Thanks!
Upvotes: 15