Search code examples
javadb2eclipselinkjpqlweblogic12c

EclipseLink jpql "where clause" comparing timestamp is not working as expected


My jpql "where clause" that selects using a timestamp column does not "filter" as expected.

It appears sensitive to the "date" portion of the timestamp, but, ignores the "time" portion.

The table1.tmstmp column is defined as: "TMSTMP TIMESTAMP NOT NULL"

The table1 entity contains the following named query:

@NamedQuery(name = "table1.getUpdTime", query = "SELECT e FROM table1 e     
WHERE e.tmstmp >= :tmstmp order by e.tmstmp asc")

The tmstmp property is defined like this:

@Column(name = "TMSTMP", nullable = false)
private Timestamp tmstmp;

It is used like this:

TypedQuery<EsEvnt> query = em.createNamedQuery("table1.getUpdTime",
table1.class).setParameter("tmstmp", tmstmp); 

For example, when the Timestamp variable ("tmstmp"), above, is equal to "2016-06-30T09:28:33.247-04:00", it returns all records where the date portion is: 2016-06-30.

Any ideas?

I'd like to depend upon the "where clause" to explicitly select using the entire timestamp.

Update

I modified my query (seemed a native query was required) using the "CAST" function, as shown below, and it appears to work consistently:

//...note, date is in ISO format...
LocalDateTime ldt = LocalDateTime.parse(tmstmpString, DateTimeFormatter.ISO_DATE_TIME);
Timestamp tmstmp = Timestamp.valueOf(ldt);
- 
-
-
// (see "native query", coded below)...
Query query = em.createNativeQuery("SELECT * FROM table1 e WHERE e.tmstmp >= CAST(?1 as TIMESTAMP)", Table1.class)  
        .setParameter(1, tmstmp);  
List<Table1> resultList = query.getResultList(); 

WebLogic 12.1.3

DB2

Java 8

EclipseLink 2.1


Solution

  • Below, is what worked for me...

    Assuming...

        //...note, date is in ISO format...
        LocalDateTime ldt = LocalDateTime.parse(tmstmpString, DateTimeFormatter.ISO_DATE_TIME);
        Timestamp tmstmp = Timestamp.valueOf(ldt);
    

    Here's one way...

        Query query = entityManager.createNativeQuery("SELECT * FROM table1 e WHERE e.tmstmp >= CAST(?1 as TIMESTAMP)", Table1.class)  
                .setParameter(1, tmstmp);  
        List<Table1> resultList = query.getResultList(); 
    

    Here's another way...

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Table1> criteriaQuery = criteriaBuilder.createQuery(Table1.class);
        Root<Table1> table1 = criteriaQuery.from(Table1.class);
    
        Expression<Byte> expression = table1.get("tmstmp"); // ...NOTE: column name is "tmstmp"...
        Expression<Timestamp> castFunction = criteriaBuilder.function("TIMESTAMP", Timestamp.class, expression);
        Predicate predicate = criteriaBuilder.greaterThanOrEqualTo(castFunction, tmstmp);
    
        //NOTE: should be able to add to predicate...
        //      e.g.,   
        //          predicate = criteriaBuilder.and(predicate, otherPredicate);
    
        criteriaQuery.where(predicate);
        TypedQuery<Table1> query = entityManager.createQuery(criteriaQuery);
        List<Table1> resultList = query.getResultList();