Временные метки, написанные java.sql.SQLData, сдвигаются на определенное количество часов в часовом поясеJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Временные метки, написанные java.sql.SQLData, сдвигаются на определенное количество часов в часовом поясе

Сообщение Anonymous »

Может кто-нибудь посоветовать, почему запись данных с использованием java.sql.SQLData сдвигает временные метки на N часов, где N — смещение часового пояса?
Справочная информация: у меня есть приложение, использующее hibernate 6 и Springboot 3 Мне нужно вызвать хранимую процедуру, которая принимает список пользовательского типа. Очень специфическая задача, ничего тривиального. Я потратил 1-2 недели на разработку того, как это сделать в Hibernate 6 и 5, и несколько дней на форумах Hibernate, общаясь с лучшими. К сожалению, это не дало никакого MWE, это должно быть возможно, никто не смог показать ни одного работающего образца. Я не хочу двигаться в этом направлении. Поэтому я реализовал это с помощью пружинной утилиты JdbcTemplate.
Состояние: реализация «работает», данные сохраняются. Но экземпляры java.sql.Timestamp сохраняются со сдвигом по времени. В реализации ниже экземпляр Instant из поля someEntity.getCalculatedTimestamp() имеет значение, скажем, 10:00:00Z. Правильный. После преобразования Timestamp.from(someEntity.getCalculatedTimestamp()); toString сообщает "сдвинуто"(12:00:00, мой TZ +2), но это нормально (tostring сообщает об этом в местном часовом поясе), устаревший toGMTString сообщает правильные данные(10:00:00 GMT). Единственный доступный метод записи этого в SQLOutput — методstream.writeTimestamp. Но когда я проверяю журналы прокси-сервера источника данных, «сдвинутая» временная метка попадает в базу данных. ТАК, я думаю, что драйвер оракула каким-то образом изменил это.
неприятный обходной путь: я думаю, я могу рассчитывать на то, что это стабильное нежелательное поведение, и просто переместить временную метку на известную величину в противоположном направлении, чтобы отмените нежелательное «исправление» драйвера Oracle, но мне это действительно не нравится. Кто-нибудь знает, почему это происходит и как это предотвратить?
реализация:
jdbcTemplate.call(con -> {
CallableStatement callableStatement = con.prepareCall(PROCEDURE_NAME);
OracleConnection oracleConnection = con.unwrap(OracleConnection.class);

Array oracleArray = oracleConnection.createOracleArray(PROCEDURE_ARRAY_TYPE_NAME,
inputArray);

callableStatement.setArray(1, oracleArray);
return callableStatement;

}, Collections.singletonList(new SqlParameter(Types.STRUCT)));

и тип каждого элемента массива:
public class TTT implements SQLData {
private static final String SQL_TYPE = "%s.%s".formatted("someSchema", "someType");

private UUID id;
private Timestamp calculatedTimestamp;

public TTT() {
}

public TTT(SomeEntity someEntity) {
this.id = someEntity.getId();
this.calculatedTimestamp = Timestamp.from(someEntity.getCalculatedTimestamp());

}

@Override
public String getSQLTypeName() {
return SQL_TYPE;
}

@Override
public void readSQL(SQLInput stream,
String typeName) {
throw new UnsupportedOperationException("Not implemented yet");
}

@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeBytes(UuidUtil.uuidToByteArray(id));
stream.writeTimestamp(calculatedTimestamp);

//unsupported, fails.
// stream.writeObject(calculatedTimestamp, OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE);
// stream.writeObject(calculatedTimestamp, OracleType.TIMESTAMP);
}
}

РЕДАКТИРОВАТЬ, обходной код:
private Timestamp nastyTimestampHackConversion(Instant instant) {
if (instant == null) {
return null;
}

long offsetSecondsDiff = ZoneId.systemDefault().getRules().getOffset(instant).getTotalSeconds();
Instant fixedInstant = instant.plus(-1*offsetSecondsDiff, ChronoUnit.SECONDS);
return Timestamp.from(fixedInstant);
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... c-number-o
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»