JodaTime и BeanPropertySqlParameterSource

#spring #postgresql #datetime #jodatime #spring-jdbc

#весна #postgresql #дата и время #jodatime #spring-jdbc

Вопрос:

Ситуация примерно такая:

В таблице базы данных PostgreSQL есть поле dateAdded , которое timestamp

Объект модели Pojo отображает это поле как

 class MyModel{
   org.joda.time.DateTime dateAdded;

}
  

Моя реализация Dao находится в шаблоне Spring JDBC и выглядит следующим образом:

 SqlParameterSource parameters = new BeanPropertySqlParameterSource(patient);
jdbcInsert.execute(parameters);
  

Я считываю модель с клиента и создаю объект, используя @Model . Пока все в порядке. Когда я выполняю это, база данных выдает исключение со словами:
[Редактировать Erwin]: Оказывается, исключение не исходит из базы данных.

 org.postgresql.util.PSQLException: Bad value for type timestamp : 2011-10-10T21:55:19.790 03:00
  

Я не хочу выполнять форматирование вручную, реализуя полный оператор INSERT, поскольку задействовано много полей.

Каково наилучшее возможное решение здесь? Есть ли способ настроить toString() DateTime для всех вызовов. Я также думал о создании унаследованного класса из DateTime, но … ммм.. это финал.

Редактировать

Согласно Эрвину, я проверил значение даты и времени ‘2011-10-10T21:55:19.790 03:00’, вставив его в фиктивную таблицу, и оно работает. Но не могу приступить к работе с JDBC. Что-то связанное с драйвером JDBC?

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

1. ‘2011-10-10T21:55:19.790 03:00’ действителен для метки времени во всех известных мне версиях PostgreSQL. Какова ваша версия? Может ли быть так, что одинарные кавычки вокруг метки времени (которые я добавил здесь) отсутствуют в вашем SQL-операторе? Если это не так, можете ли вы показать нам соответствующий журнал сервера postgresql, это устранит путаницу.

2. Postgres 9. Дело в том, что я не пишу здесь инструкцию SQL Insert. Я просто создаю объект модели, оборачиваю его с помощью BeanPropertySqlParameterSource и помещаю его в объект Spring JDBC SimpleJdbcInsert. Это внутренне позаботится о вставках SQL. И вы правы. Я только что протестировал то же значение, используя фиктивную таблицу, и оно работает. Это совершенно странно.

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

4. Не могу помочь вам с частью JDBC, мой опыт связан с postgresql. Если JDBC просто ошибается в синтаксисе, вы можете обойти проблему, предоставив альтернативный синтаксис, например '2011-10-10 21:55:19.790 03:00' . T Хотя это совершенно законно, это необычно.

5. Спасибо Эрвину. Надеюсь, у кого-нибудь еще есть ответ. Как вы сказали, я тоже чувствую это странно.

Ответ №1:

Проблема здесь в том, что JdbcTemplate используется подготовленный оператор, а затем привязка значений. Рассматриваемое поле имеет тип timestamp — поэтому его необходимо установить как a java.sql.Date . В этом случае spring вызывает универсальный setObject метод, передавая ему DateTime экземпляр Joda Time. Драйвер не знает, как преобразовать это в a java.sql.Date — отсюда и ошибка.

Чтобы устранить эту проблему, вы можете расширить BeanPropertySqlParameterSource переопределение getValue метода. Если тип объекта joda.time.DateTime равен, преобразуйте его в java.util.Date объект и верните его. Это должно устранить проблему.

 class CustomBeanPropertySqlParameterSource extends BeanPropertySqlParameterSource {
  @Override
  Object getValue(String paramName) {
     Object result = super.getValue(paramName);
     if (result instanceof DateTime) {
        return ((DateTime) result).toDate();
     } else {
        return result;
     }
  }
}