Некоторая предыстория:
У меня есть Java 1.6 webapp, работающий на Tomcat 7. База данных - это MySQL 5.5. Раньше я использовал драйвер Mysql JDBC 5.1.23 для подключения к БД. Все сработало. Недавно я обновился до драйвера Mysql JDBC 5.1.33. После обновления Tomcat выбросит эту ошибку при запуске приложения.
WARNING: Unexpected exception resolving reference
java.sql.SQLException: The server timezone value 'UTC' is unrecognized or represents more than one timezone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc timezone value if you want to utilize timezone support.
Почему это происходит?
По-видимому, чтобы получить версию 5.1.33 драйвера JDBC MySQL для работы с часовым поясом UTC, нужно явно указать serverTimezone
в строке подключения.
jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Если вы используете Maven, вы можете просто установить другую версию соединителя MySQL (у меня была такая же ошибка, поэтому я изменил ее с 6.0.2 на 5.1.39) в pom.xml
:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
Как сообщается в других ответах, эта проблема была исправлена в версиях 6.0.3 или выше, поэтому вы можете использовать обновленную версию:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.3</version>
</dependency>
Maven автоматически перестроит ваш проект после сохранения файла pom.xml
.
Я решил эту проблему, настроив MySQL.
SET GLOBAL time_zone = '+3:00';
jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow
. Похоже, MySQL-разъем не понимает короткие имена часовых поясов.
Это ошибка в mysql-connector-java от версии 5.1.33 до 5.1.37. Я сообщил об этом здесь: http://bugs.mysql.com/bug.php?id=79343
Отредактировано: Это было исправлено из mysql-connector-java 5.1.39
Это была опечатка в классе TimeUtil в методе loadTimeZoneMappings, которая вызывает поиск NPE файла /com/mysql/jdbc/TimeZoneMapping.properties. Если вы посмотрите на код, файл должен находиться в загрузчике классов TimeUtil, а не TimeZone:
TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);
Параметр useLegacyDatetimeCode позволяет автоматически корректировать разницу между часовыми поясами клиента и сервера при использовании дат. Таким образом, это помогает вам точно не указывать часовые пояса в каждой части. Хотя использование параметра serverTimeZone является обходным решением, а между тем патч выпущен, вы можете попробовать лучше исправить код самостоятельно, как я.
Если это автономное приложение, попробуйте просто добавить скорректированный класс com/mysql/jdbc/TimeUtil для вашего кода и будьте осторожны с порядком загрузки контейнера. Это может помочь: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html
Если это веб-приложение, более простым решением является создание собственного mysql-connector-java-5.1.37-patched.jar, подставляя .class напрямую в оригинальную банку.
Строка подключения должна быть установлена следующим образом:
jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Если вы определяете соединение в файле xml
(например, persistence.xml
, standalone-full.xml
и т.д.), вместо &
вы должны использовать &
или использовать блок CDATA
.
Я решил поставить ниже строку подключения в URL-адрес
jdbc:mysql://localhost:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
У меня такая же проблема, и я решил, что добавляет только "? ServerTimezone = UTC" в мое строковое соединение.
#синошь моя проблема:
java.sql.SQLException: значение часового пояса сервера "CEST" непризнано или представляет собой более одного часового пояса. Вы должны настроить драйвер сервера или JDBC (через свойство конфигурации serverTimezone), чтобы использовать более определенное значение часового пояса, если вы хотите использовать поддержку часового пояса.
my dbDriver = com.mysql.jdbc.Driver
my jar = mysql-connector-java-8.0.12.jar
my java = 1.8
my tomcat = Apache Tomcat Version 8.5.32
my MySql server = MySql ver.8.0.12
Я добавил в конфигурационный файл mysql в разделе [mysqld]
default_time_zone='+03:00'
И перезагрузите сервер mysql:
sudo service mysql restart
Где +03: 00 мой часовой пояс UTC.
Путь к файлу конфигурации на моем os ubuntu 16.04:
/etc/mysql/mysql.conf.d/mysqld.cnf
ПРЕДУПРЕЖДЕНИЕ: ЕСЛИ ВАША ВРЕМЕННАЯ ЗОНА ИМЕЕТ ЛЕТО И ЗИМНЕЕ ВРЕМЯ. ВЫ ДОЛЖНЫ ИЗМЕНИТЬ UTC В КОНФИГУКЕ, ЧТО ВРЕМЯ ИЗМЕНЕНИЯ. ДВАЖДЫ В ГОД (ПОСЛЕДУЮЩАЯ) ИЛИ УСТАНОВИТЕ КРОНТАБ С СУДО.
Соединение с моим url jdbc:
"jdbc:mysql://localhost/java"
После прочтения нескольких постов на эту тему, тестирования различных конфигураций и на основе некоторых выводов из этой ветки ошибок MySQL я понял следующее:
useLegacyDatetimeCode=true
, что в сочетании с useJDBCCompliantTimezoneShift=true
заставляло бы приложение получать часовой пояс базы данных при каждом подключении. В этом режиме часовые пояса GMT, такие как "Британское летнее время", будут преобразованы во внутренний формат Java/JDBC. Новые часовые пояса могут быть определены в файле .properties, таком как этотuseJDBCCompliantTimezoneShift
) и устаревший формат времени (useLegacyDatetimeCode
) были удалены (см. Журнал изменений коннектора mysql jdbc). поэтому установка этих двух параметров не имеет никакого эффекта, поскольку они полностью игнорируются (новое значение по умолчанию - useLegacyDateTimeCode=false
)serverTimezone
стала обязательной, если какой-либо из часовых поясов (серверы приложений/баз данных) не в формате "UTC + xx" или "GMT + xx"jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC
, даже если ваши серверы приложений/баз данных не находятся в этом часовом поясе. Это важно для подключения приложения Синхронизация строки + базы данных с одним и тем же часовым поясом. Другими словами, просто установка serverTimezone = UTC с другим часовым поясом на сервере базы данных сместит любые даты, извлеченные из базы данных.default-time-zone='+00:00'
(подробности в https://stackoverflow.com/questions/19903610/how-to-set-permanent-default-timezone-in-mysql-server) Все, что нам нужно, чтобы исправить проблему с serverTimezone
:
String url = "jdbc:mysql://localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()
Я использую mysql-connector-java-8.0.13 и имею ту же проблему. Я создал свою базу данных в консоли командной строки и решил эту проблему с помощью решения @Dimitry Rud в командной строке:
SET GLOBAL time_zone = '-6:00';
Мне не нужно было ничего перезапускать, установить время и сразу запустить мой код в eclipse, без проблем.
Предполагается, что ошибка исправлена в более старой версии, но я думаю, что получил эту ошибку, потому что после создания базы данных в консоли я этого не задал. Я не использую workbench или другое приложение для управления этим, а не консолью.
У меня также была такая же проблема в LibreOffice Base. Поэтому я просто указал в строке подключения не "летнее время".
Я пробовал без "& serverTimezone = MST", но это тоже не удалось.
Я также попытался "& serverTimezone = MDT", и это не удалось, поэтому по какой-то причине ему не нравится переход на летнее время!
Я решил эту проблему без какого-либо изменения кода. просто установите время системы и установите часовой пояс. В моем случае часовой пояс по умолчанию был UTC, который я изменил на свой локальный часовой пояс. После того, как я перезапустил все службы, все сработало для меня.
Из mysql workbench запустите следующие операторы sql:
с помощью следующих операторов sql проверьте, были ли установлены значения:
SELECT @@global.time_zone, @@session.time_zone;
Решение @Ingvar сработало.
String url = "jdbc:mysql://localhost:330/db?serverTimezone="+TimeZone.getDefault().getID()
Согласитесь с ответом @bluecollarcoder, но лучше использовать TimeZone.getDefault().getID();
в конце строки подключения:
"jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=" + TimeZone.getDefault().getID();
В этом случае параметр Timezone
автоматически обновляется в зависимости от часового пояса локального компьютера.
package pack1;
import java.sql.Connection;
import java.sql.DriverManager;
import javax.swing.JOptionPane;
public class sqliteConnection {
Connection conn=null;
public static Connection dbConnector() {
try {Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306", "root", "");
JOptionPane.showMessageDialog(null, "connection is succesful");
return conn;
} catch(Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
////you need also to execute this in database ===> SET GLOBAL time_zone = '+3:00';
}
}
}