Использование дат в предложении Criteria Query where

У меня есть объект с полем java.util.Date, хранящимся как TemporalType.DATE. При передаче java.util.Date с часами, минутами или секундами в предложение where запроса критериев я не могу получить совпадение из базы данных.

Установка представляет собой встроенную базу данных H2 в Spring с Hibernate. Я пробовал использовать PostgreSQL вместо H2, и это работает. Я также пытался установить H2 в режиме PostgreSQL, но это ничего не меняет.

Учитывая сущность

@Entity
public class SomeEntity {

    @Id
    private int id;

    @Temporal(TemporalType.DATE)
    private java.util.Date aDate;

    public int getId() {
        return id;
    }

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

    public Date getDate() {
        return aDate;
    }

    public void setDate(Date aDate) {
        this.aDate = aDate;
    }
}

Следующий запрос возвращает совпадение только в том случае, если для часов, минут и секунд параметра установлено значение 0.

public List<SomeEntity> someQueryOnDate(Date date) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<SomeEntity> query = cb.createQuery(SomeEntity.class);

    Root<SomeEntity> root = query.from(SomeEntity.class);
    Predicate dateEquals = cb.equal(root.get(SomeEntity_.date), date);
    query.where(dateEquals);

    // This list is always empty if the date in the predicate has a time part
    return em.createQuery(query).getResultList(); 
}

Полный пример следует. Тест терпит неудачу в последнем утверждении, где я запрашиваю базу данных, используя дату с установленными часами, минутами и секундами.

@Test
public void testDateEquals() throws ParseException {
    Date dateWithoutTime = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-03");
    Date dateWithTime    = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-07-03 09:45:01");

    createEntity(dateWithoutTime);

    List<SomeEntity> entitiesMatchingDateWithTime    = listAllEntitiesWithDate(dateWithTime);
    List<SomeEntity> entitiesMatchingDateWithoutTime = listAllEntitiesWithDate(dateWithoutTime);

    Assert.assertFalse("No entities matched the date without time", entitiesMatchingDateWithoutTime.isEmpty());
    Assert.assertFalse("No entities matched the date with time"   , entitiesMatchingDateWithTime.isEmpty());
}

private void createEntity(Date d) {
    SomeEntity entity = new SomeEntity();
    entity.setDate(d);
    em.persist(entity);

    // For good measure
    em.flush();
    em.clear();
}

private List<SomeEntity> listAllEntitiesWithDate(Date date) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<SomeEntity> query = cb.createQuery(SomeEntity.class);

    Root<SomeEntity> root = query.from(SomeEntity.class);
    Predicate dateEquals = cb.equal(root.get(SomeEntity_.date), date);
    query.where(dateEquals);

    return em.createQuery(query).getResultList();
}

person Thinner    schedule 03.07.2014    source источник


Ответы (1)


Возможно, решение представлено здесь:

Критерии гибернации для дат

Вы можете использовать Restrictions для сравнения дат.

person Genzotto    schedule 03.07.2014
comment
Спасибо за ответ! Я посмотрю на Ограничения. Но поскольку я знаю, что это работает в PostgreSQL без изменения запроса, я бы предпочел настроить H2 для другой обработки дат. Предположим, что это возможно :) - person Thinner; 03.07.2014