Possible issue with timestamps

#1

Hi,

If I query doing something like: select c from CDI c where c.creationDate > {ts '2012-03-29 11:00:00} and c.creationDate < {ts '2012-03-29 12:00:00'} the test fails. Its ONLY for 12:00:00. When I started digging I found that if I queried 00:00:00 to 00:25:00 and then did 12:00:00 to 12:25:00 I got IDENTICAL results. For some reason 12:00:00 is being treated the same as 00:00:00. All other hours seem to be fine.

Thankfully if I do: select c from CDI c where c.creationDate > :startDate and c.creationDate < :endDate and pass the dates in as parameters it works correctly.

I have attached a testcase.

Paul.

#2

Thank you for this report and for the test. Here is the same test in one class format (please use this format in your posts when possible). Build 2.3.7_10 fixes this time parsing issue.

import static org.junit.Assert.*;

import java.io.*;
import java.util.*;

import javax.jdo.annotations.*;
import javax.persistence.*;

import org.junit.*;


public class T737 {

    @Test
    public void test() {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory("objectdb:$objectdb/db/test.tmp;drop");
        EntityManager em = emf.createEntityManager();
    
        Calendar cal1 = new GregorianCalendar(2012, Calendar.MARCH, 29, 0, 5); //fives after midnight
        Calendar cal2 = new GregorianCalendar(2012, Calendar.MARCH, 29, 0, 10); //ten after midnight
        Calendar cal3 = new GregorianCalendar(2012, Calendar.MARCH, 29, 0, 30); //thrity after midnight
        Calendar cal4 = new GregorianCalendar(2012, Calendar.MARCH, 29, 1, 5); //fives after one
        Calendar cal5 = new GregorianCalendar(2012, Calendar.MARCH, 29, 1, 30); //thirty after one
        Calendar cal6 = new GregorianCalendar(2012, Calendar.MARCH, 29, 2, 15); //quarter after two
        Calendar cal7 = new GregorianCalendar(2012, Calendar.MARCH, 29, 3, 15);
        Calendar cal8 = new GregorianCalendar(2012, Calendar.MARCH, 29, 4, 15);
        Calendar cal9 = new GregorianCalendar(2012, Calendar.MARCH, 29, 5, 15);
        Calendar cal10 = new GregorianCalendar(2012, Calendar.MARCH, 29, 6, 15);
        Calendar cal11 = new GregorianCalendar(2012, Calendar.MARCH, 29, 7, 15);
        Calendar cal12 = new GregorianCalendar(2012, Calendar.MARCH, 29, 8, 15);
        Calendar cal13 = new GregorianCalendar(2012, Calendar.MARCH, 29, 9, 15);
        Calendar cal14 = new GregorianCalendar(2012, Calendar.MARCH, 29, 10, 15);
        Calendar cal15 = new GregorianCalendar(2012, Calendar.MARCH, 29, 11, 15);
        Calendar cal16 = new GregorianCalendar(2012, Calendar.MARCH, 29, 12, 3);
        Calendar cal17 = new GregorianCalendar(2012, Calendar.MARCH, 29, 12, 17);
        Calendar cal18 = new GregorianCalendar(2012, Calendar.MARCH, 29, 12, 37);
        Calendar cal19 = new GregorianCalendar(2012, Calendar.MARCH, 29, 13, 15);
        Calendar cal20 = new GregorianCalendar(2012, Calendar.MARCH, 29, 14, 15);
        Calendar cal21 = new GregorianCalendar(2012, Calendar.MARCH, 29, 15, 15);
        Calendar cal22 = new GregorianCalendar(2012, Calendar.MARCH, 29, 16, 15);
       
        em.getTransaction().begin();
        CDI cdi1 = new CDI("first1", "last1", cal1.getTime());
        CDI cdi2 = new CDI("first2", "last2", cal2.getTime());
        CDI cdi3 = new CDI("first3", "last3", cal3.getTime());
        CDI cdi4 = new CDI("first4", "last4", cal4.getTime());
        CDI cdi5 = new CDI("first5", "last5", cal5.getTime());
        CDI cdi6 = new CDI("first6", "last6", cal6.getTime());
        CDI cdi7 = new CDI("first7", "last7", cal7.getTime());
        CDI cdi8 = new CDI("first8", "last8", cal8.getTime());
        CDI cdi9 = new CDI("first9", "last9", cal9.getTime());
        CDI cdi10 = new CDI("first10", "last10", cal10.getTime());
        CDI cdi11 = new CDI("first11", "last11", cal11.getTime());
        CDI cdi12 = new CDI("first12", "last12", cal12.getTime());
        CDI cdi13 = new CDI("first13", "last13", cal13.getTime());
        CDI cdi14 = new CDI("first14", "last14", cal14.getTime());
        CDI cdi15 = new CDI("first15", "last15", cal15.getTime());
        CDI cdi16 = new CDI("first16", "last16", cal16.getTime());
        CDI cdi17 = new CDI("first17", "last17", cal17.getTime());
        CDI cdi18 = new CDI("first18", "last18", cal18.getTime());
        CDI cdi19 = new CDI("first19", "last19", cal19.getTime());
        CDI cdi20 = new CDI("first20", "last20", cal20.getTime());
        CDI cdi21 = new CDI("first21", "last21", cal21.getTime());
        CDI cdi22 = new CDI("first22", "last22", cal22.getTime());
       
        em.persist(cdi1);
        em.persist(cdi2);
        em.persist(cdi3);
        em.persist(cdi4);
        em.persist(cdi5);
        em.persist(cdi6);
        em.persist(cdi7);
        em.persist(cdi8);
        em.persist(cdi9);
        em.persist(cdi10);
        em.persist(cdi11);
        em.persist(cdi12);
        em.persist(cdi13);
        em.persist(cdi14);
        em.persist(cdi15);
        em.persist(cdi16);
        em.persist(cdi17);
        em.persist(cdi18);
        em.persist(cdi19);
        em.persist(cdi20);
        em.persist(cdi21);
        em.persist(cdi22);
        em.getTransaction().commit();
    
        TypedQuery<Long> query = em.createQuery("SELECT count(c) FROM CDI c", Long.class);
        Long cdiCount = query.getSingleResult();
        assertEquals(22, cdiCount.intValue());
       
        query = em.createQuery("SELECT count(c) FROM CDI c where c.creationDate > {ts '2012-03-29 00:00:00'} and c.creationDate < {ts '2012-03-29 00:59:00'}", Long.class);
        cdiCount = query.getSingleResult();
        assertEquals(3, cdiCount.intValue());
       
        query = em.createQuery("SELECT count(c) FROM CDI c where c.creationDate > :startdate and c.creationDate < :enddate", Long.class);
        Calendar startDate = new GregorianCalendar(2012, Calendar.MARCH, 29, 0, 0);
        query.setParameter("startdate", startDate);
        Calendar endDate = new GregorianCalendar(2012, Calendar.MARCH, 29, 1, 0);
        query.setParameter("enddate", endDate);
        cdiCount = query.getSingleResult();
        assertEquals(3, cdiCount.intValue());
       
        query = em.createQuery("SELECT count(c) FROM CDI c where c.creationDate > :startdate and c.creationDate < :enddate", Long.class);
        startDate = new GregorianCalendar(2012, Calendar.MARCH, 29, 11, 0);
        query.setParameter("startdate", startDate);
        endDate = new GregorianCalendar(2012, Calendar.MARCH, 29, 12, 00);
        query.setParameter("enddate", endDate);
        cdiCount = query.getSingleResult();
        assertEquals(1, cdiCount.intValue());
       
        TypedQuery<CDI> query2 = em.createQuery("SELECT c FROM CDI c where c.creationDate > {ts '2012-03-29 00:00:00'} and c.creationDate < {ts '2012-03-29 00:08:00'}", CDI.class);
        List<CDI> results = query2.getResultList();
        assertEquals(1, results.size());
        assertEquals("first1", results.get(0).getFirstname());
       
        query2 = em.createQuery("SELECT c FROM CDI c where c.creationDate > {ts '2012-03-29 12:00:00'} and c.creationDate < {ts '2012-03-29 12:08:00'}", CDI.class);
        results = query2.getResultList();
        assertEquals(1, results.size());
        assertEquals("first16", results.get(0).getFirstname());
       
        query = em.createQuery("SELECT count(c) FROM CDI c where c.creationDate > {ts '2012-03-29 11:00:00'} and c.creationDate < {ts '2012-03-29 12:00:00'}", Long.class);
        cdiCount = query.getSingleResult();
        assertEquals(1, cdiCount.intValue());

        em.close();
        emf.close();
    }

    @Entity
    @TableGenerator(name="IdTableGen", initialValue=1, allocationSize=50)
    public static class CDI implements Serializable{
        private static final long serialVersionUID = 1L;
      
        private Date creationDate = null;
        private String firstname = null;
        private String lastname = null;
       
        private long id;
       
        public CDI() {
           
        }
       
        public CDI(String firstname, String lastname) {
            this.firstname = firstname;
            this.lastname = lastname;
            this.creationDate = new Date();
        }
       
        public CDI(String firstname, String lastname, Date creationDate) {
            this.firstname = firstname;
            this.lastname = lastname;
            this.creationDate = creationDate;
        }
           
        @Temporal(TemporalType.TIMESTAMP)
        public Date getCreationDate() {
            return creationDate;
        }
       
        public void setCreationDate(Date creationDate) {
            this.creationDate = creationDate;
        }
       
        @Id
        @GeneratedValue(strategy=GenerationType.TABLE, generator="IdTableGen")
        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        @Index(unique="false")
        public String getFirstname() {
            return firstname;
        }

        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }

        @Index(unique="false")
        public String getLastname() {
            return lastname;
        }

        public void setLastname(String lastname) {
            this.lastname = lastname;
        }
    }
}
ObjectDB Support
#3

Fixed. Thanks.

Reply