Выбор неправильного описания типа в режиме гибернации

#hibernate #jpa #calendar #jaxb #glassfish-5

#переход в спящий режим #jpa #Календарь #jaxb #glassfish-5

Вопрос:

Я использую Hibernate 5 с JPA. Ниже приведены некоторые фрагменты кода. Объект построен с использованием JAXB, и я предпочитаю не изменять тип ответа из Календаря, поскольку это повлияет и на другие приложения.

 class Object {
    @XmlSchemaType(
        name = "dateTime"
    )
    @Temporal(TemporalType.TIMESTAMP)
    protected Calendar startDate;
}
  

Выполняемый запрос

 select count(m) from Message as m where start_date > :startDate
  

Параметр устанавливается следующим образом

 query.setParameter("startDate", object.getStartDate(), TemporalType.TIMESTAMP);
  

Однако при выполнении кода, который вызывает запрос, я получаю следующую трассировку стека.

 Caused by: java.lang.ClassCastException: java.util.GregorianCalendar cannot be cast to java.util.Date
    at org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor.unwrap(JdbcTimestampTypeDescriptor.java:24)
    at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$1.doBind(TimestampTypeDescriptor.java:48)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:271)
    at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:53)
    at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:648)
    at org.hibernate.loader.Loader.bindPreparedStatement(Loader.java:2113)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2090)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2022)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2000)
    at org.hibernate.loader.Loader.doQuery(Loader.java:951)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:352)
    at org.hibernate.loader.Loader.doList(Loader.java:2831)
    at org.hibernate.loader.Loader.doList(Loader.java:2813)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2645)
    at org.hibernate.loader.Loader.list(Loader.java:2640)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1412)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1565)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
    at org.hibernate.query.Query.getResultList(Query.java:165)
  

Обратите внимание, что он выбирает JdbcTimestampTypeDescriptor, который жестко запрограммирован для даты типа объекта, в которой потенциально заключается моя проблема.

Вопрос

  • Что я делаю не так?
  • Как я могу повлиять на режим гибернации, чтобы выбрать CalendarTypeDescriptor? Будет ли это правильным подходом, если да?

ОБНОВЛЕНИЕ Я не хочу менять код, поскольку этот аналогичный код находится в нескольких местах / репозиториях, и я не хочу обновлять их все

Ответ №1:

Вы можете преобразовать свой объект календаря в дату с getTime() помощью метода:

 query.setParameter("startDate", object.getStartDate().getTime(), TemporalType.TIMESTAMP);
  

Комментарии:

1. Я бы предпочел этого не делать, поскольку это означало бы обновление множества компонентов, которые используют эту модель. Ищите опцию через конфигурацию гибернации или эквивалент, пожалуйста