#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;
}
}
}