Search code examples
javagenericsjpacriteria

Java Persistence Criterias; Cast Expression<Timestamp> to Expression<Long>?


I am using the CriteriaBuilder and CriteriaQuery to build my query to the database, but I have encountered an issue that I do not know how to solve, since I am very new to this whole ordeal called JPA.

In Java, I have a property called timestamp for a class called Report, and it is set to the same corresponding @TemporalType. I also have a class called Affiliate which has a list of Report objects.

In my query, I want to fetch all the Affiliate objects that do not have a Report in the last Affiliate.maxSilenceMinutes.

My questions:

  1. Are there any ways in standardized JPA to modify dates? Like a CriteriaBuilder.subtractMilliseconds(Expression<Timestamp>, Long) of sorts?
  2. If not, is there a way to cast Expression<Timestamp> to Expression<Long> so that I can subtract on a currentTimestamp literal to get the minimum value for a CriteriaBuilder.lessThanOrEqualTo(greatestReportTimestampMs, minimumAllowedMs)?

I know this might feel like a confusing question, but the main part is simply: Is it possible to go Expression<Timestamp> to Expression<Long>? It throws an exception for me if I try to use the .as(Long.class) method, but which should be the default underlying data type in most DBs anyway?

Hope you guys can help, since I feel kind of stuck :)


Solution

  • If you know the value you want to subtract at the time of querying, you can subtract beforehand:

    Calendar c = new Calendar();
    c.setTime(timestamp.getTimestamp());
    c.add(DAY, - someNumberOfDays);  //or whatever unit you want
    Date d = c.getTime();
    

    If not, you probably need to call a database function to do the subtraction, via CriteriaBuilder.function()

    CriteriaBuilder.lessThanOrEqual() works on Comparables. Timestamps are comparable. So you could construct a Timestamp via new Timestamp(long ms) and compare it with the other expression.

    I hope this helps.