Столбцы даты в SQL-сервере (MSSQL-JDBC 3.0), работающем под Java 1.7.0, получены как 2 дня назад - PullRequest
16 голосов
/ 11 октября 2011

У меня странные эффекты при извлечении столбцов типа 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 тогда ... мы вчера поменяли производительный сервер (я исправил места, где приложение полагалось на особенности драйвера), и до сих пор у нас не было проблем.

Ответы [ 5 ]

10 голосов
/ 16 декабря 2011

Спасибо за ваш отзыв.Драйвер Microsoft JDBC для SQL Server пока не поддерживает JRE 1.7.

Нам известно о проблеме getDate между нашим драйвером JDBC и JRE 1.7, и мы рассматриваем возможность публикации исправления, позволяющего клиентам двигаться вперед с не-производственное тестирование нашего драйвера с JRE 1.7.

Мы опубликуем ссылку на исправление в нашем блоге, как только оно будет доступно.http://blogs.msdn.com/b/jdbcteam/

Исправление теперь доступно. http://blogs.msdn.com/b/jdbcteam/archive/2012/01/20/hotfix-available-for-date-issue-when-using-jre-1-7.aspx

Наш блог также содержит информацию об известных проблемах с JRE 1.6u29 и 1.6u30.

Shamitha Reddy Program Manager - драйвер Microsoft JDBC для SQL Server

8 голосов
/ 14 октября 2011

У меня нет совсем ответа для вас.Но я воссоздал вашу ситуацию, как вы описали.То же самое с драйвером jdbc v3.101, v3.202 и v4.ctp3 при запуске под jdk1.7.Тем не менее, драйвер v2 от MS дает ожидаемый ответ как для jdk1.6, так и для jdk1.7.Если вам нужно быстрое исправление и вы можете перейти к более старому драйверу jdbc, это может сработать для вас.

Другие мысли касаются того, как драйвер jdbc MS обрабатывает даты и преобразование объектов Date между SQL Server и jvm.Поскольку в хранилище даты нет часового пояса, интерпретация объекта Date драйвером основана на часовом поясе по умолчанию для машины, на которой работает драйвер jdbc.Например, если вы храните маленькую дату «2011-10-11 12:00» и извлекаете ее с компьютера с часовым поясом по умолчанию, установленным на GMT-7, то итоговое время UTC объекта Date будет равно «2011-10».-11 19:00 '.Возможно, что в jdk1.7 есть некоторые изменения, которые влияют на этот процесс преобразования в драйвере, что приводит к дикому смещению.Вы можете поэкспериментировать с методом ResultSet.getDate (column, Calendar), чтобы увидеть, дает ли Календарь с определенным часовым поясом нужный вам результат или помогает понять, почему вы видите странное смещение в преобразовании.

2 голосов
/ 13 октября 2011

У меня нет установки SQL Server, но я не могу воспроизвести вашу проблему с PostgreSQL 9.0 и MySQL 5.1 на Windows 7 x64 с JDK 1.7.0. Таким образом, JDK 1.7.0 может быть исключен из числа подозреваемых. У меня сложилось впечатление, что здесь виноват драйвер JDBC для SQL Server. Я бы предложил вместо этого использовать драйвер JDBC jTDS . Его всегда хвалили за лучшую производительность и стабильность, в отличие от предоставляемого MS драйвера JDBC для SQL Server.

1 голос
/ 10 января 2014

Информацию и ссылку для загрузки исправления от службы поддержки Microsoft можно найти здесь:

http://support.microsoft.com/kb/2652061

У меня возникла та же проблема, когда дата была отменена на два дня, и это исправление исправило ее.

0 голосов
/ 02 ноября 2011

Это также проблема в OpenJDK 1.6.0_20. Тем не менее, драйвер mssql прекрасно работает с Suns JRE 1.6.0_16.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...