O problema é que Java
Date
objetos não armazenam um fuso horário. O valor é sempre em UTC e é analisado e formatado em um determinado fuso horário, geralmente o fuso horário padrão da JVM. Oracle
DATE
colunas também são armazenadas sem fuso horário, mas devem representar a data conforme vista pelo usuário. Em 99,99% dos casos, isso significa a data no fuso horário padrão da JVM. Portanto, o driver JDBC usa o
Timestamp
/ Date
value, que está em UTC, o converte para o fuso horário padrão e o salva no banco de dados. Você está usando o
PreparedStatement.setTimestamp(int parameterIndex, Timestamp x)
método. Para controlar o fuso horário, use o PreparedStatement.setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
método. Citando o javadoc: