У меня странные эффекты при извлечении столбцов типа DATE из SQLServer2008 с помощью Microsoft JDBC-Driver версии 3.0 при работе под официальным Oracle JDK 1.7.0. ОС хоста - Windows Server 2003.
Все столбцы Date извлекаются как два дня в прошлом относительно значения, фактически сохраненного в столбце.
Я подготовил минимальный пример кода, чтобы проверить это (таблица тестов и данные):
CREATE TABLE Java7DateTest (
dateColumn DATE
);
INSERT INTO Java7DateTest VALUES('2011-10-10');
код:
public class Java7SQLDateTest {
public static void main(final String[] argv) {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection connection = DriverManager.getConnection(
"jdbc:sqlserver://192.168.0.1:1433;databaseName=dbNameHere",
"user", "password");
PreparedStatement statement = connection.prepareStatement("SELECT * FROM Java7DateTest");
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
final java.sql.Date date = resultSet.getDate("dateColumn");
final String str = resultSet.getString("dateColumn");
System.out.println(date + " (raw: " + str + ")");
}
resultSet.close();
statement.close();
connection.close();
} catch (final Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
}
}
Запуск этого кода на вышеприведенных конфигурациях печатает: "2011-10-08 (raw: 2011-10-08)". В JRE 1.6.0_27 он печатает: "2011-10-10 (raw: 2011-10-10)"
Я не мог найти ничего похожего на мою проблему с Google, поэтому я предполагаю, что ее либо что-то глупое я забыл, либо никто еще не использует Java7.
Может ли кто-нибудь подтвердить эту проблему? Каковы мои альтернативы, если я все еще хочу использовать Java7?
Изменить: Проблема возникает даже при работе с -Xint, поэтому ее не вызывают ошибки Hotspot.
Edit2: старые драйверы (Microsoft 1.28) работают правильно с JDK1.7.0 (мы использовали этот драйвер, возможно, два года назад, я думаю). jTDS также отлично работает с примером. Я рассматриваю возможность перехода на jTDS, но я неохотно это делаю, потому что не имею ни малейшего представления о влиянии на нашу продуктивную среду. В идеале это должно сработать, но это то, что я верил, когда я переключил свой блок разработчиков на Java7. В рабочей среде есть одна довольно жирная база данных, которая слишком велика для создания копии для тестирования (или, скорее, у нашего сервера осталось так мало диска). Поэтому настройка тестовой среды для этого приложения не является чрезмерной, поэтому для этого мне нужно будет сшить сжатую базу данных.
Edit3: jTDS имеет свой собственный набор уловов. Я нашел поведенческую разницу, которая ломает одно из наших приложений. ResultSet.getObject() возвращает разные типы объектов для столбцов SmallInt в зависимости от драйвера (Short vs Integer). Кроме того, jTDS не реализует интерфейс подключения JDBC4, Connect.isValid() не поддерживается.
Edit4: на прошлой неделе я заметил, что MSSQL-JDBC 3.0 отказывается подключиться к любой базе данных после обновления до JDK1.6.0_29. jTDS это тогда... вчера мы переключили продуктивный сервер (я фиксировал места буксировки, где приложение полагалось на особенности драйвера), и до сих пор у нас не было проблем.