У меня странные эффекты при извлечении столбцов типа DATE из SQLServer2008 с использованием Microsoft JDBC-Driver version 3.0 при работе под официальным Oracle JDK 1.7.0. ОС хоста - Windows Server 2003.
Все столбцы даты извлекаются как два дней в прошлом относительно значения, фактически сохраненного в столбце.
Я подготовил минимальный пример кода, чтобы проверить это (таблица и данные теста):
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, но я не хочу этого делать, потому что у меня нет ни малейшего представления о том, какое влияние может оказать наша производственная среда. В идеале это должно просто работать, но это то, во что я верил, когда я переключил свой dev box на Java7, тоже.
В производственной среде есть одна довольно толстая база данных, слишком большая, чтобы создать копию для тестирования (точнее, на нашем сервере осталось так мало диска). Поэтому настройка тестовой среды для этого одного приложения не так уж и проста, для этого мне пришлось бы создать сокращенную базу данных.
Edit3: jTDS имеет свой собственный набор прикрепленных уловов. Я обнаружил поведенческую разницу, которая нарушает одно из наших приложений. ResultSet.getObject () возвращает различные типы объектов для столбцов SmallInt в зависимости от драйвера (Short против Integer). Также в jTDS не реализован интерфейс подключения JDBC4, Connect.isValid () не поддерживается.
Edit4: на прошлой неделе я заметил, что MSSQL-JDBC 3.0 отказывается подключаться к любой БД после того, как я обновил JDK1.6.0_29. jTDS тогда ... мы вчера поменяли производительный сервер (я исправил места, где приложение полагалось на особенности драйвера), и до сих пор у нас не было проблем.