web-dev-qa-db-de.com

MySQL JDBC Driver 5.1.33 - Zeitzonenproblem

Einige hintergrund:

Ich habe eine Java 1.6-Webanwendung, die auf Tomcat 7 ausgeführt wird. Die Datenbank ist MySQL 5.5. Zuvor habe ich den Mysql-JDBC-Treiber 5.1.23 verwendet, um eine Verbindung zur DB herzustellen. Alles hat funktioniert. Ich habe kürzlich ein Upgrade auf den Mysql JDBC-Treiber 5.1.33 durchgeführt. Nach dem Upgrade hat Tomcat beim Starten der App diesen Fehler ausgegeben.

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.

Warum passiert dies?

162
bluecollarcoder

Um Version 5.1.33 des MySQL-JDBC-Treibers für die Arbeit mit der UTC-Zeitzone zu erhalten, muss anscheinend die serverTimezone explizit in der Verbindungszeichenfolge angegeben werden.

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
297
bluecollarcoder

Wenn Sie Maven verwenden, können Sie einfach eine andere MySQL-Connector-Version festlegen (ich hatte den gleichen Fehler, daher habe ich von 6.0.2 auf 5.1.39 geändert) in pom.xml:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-Java</artifactId>
    <version>5.1.39</version>
</dependency>

Wie in anderen Antworten berichtet, wurde dieses Problem in den Versionen 6.0.3 oder höher behoben, sodass Sie die aktualisierte Version verwenden können:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-Java</artifactId>
    <version>6.0.3</version>
</dependency>

Nachdem Sie die pom.xml-Datei gespeichert haben, erstellt Maven Ihr Projekt automatisch neu. 

Dies ist ein Fehler in MySQL-Connector-Java von Version 5.1.33 bis 5.1.37 ... Ich habe ihn hier gemeldet: http://bugs.mysql.com/bug.php?id=79343

Editiert: Dies wurde korrigiert von mysql-connector-Java 5.1.39.

Es war ein Tippfehler in der TimeUtil-Klasse in der loadTimeZoneMappings-Methode, durch den eine NPE-Datei mit dem Namen /com/mysql/jdbc/TimeZoneMapping.properties ausgelöst wird. Wenn Sie sich den Code ansehen, sollte sich die Datei im TimeUtil-Klassenladeprogramm und nicht in TimeZone befinden:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

Mit dem Parameter useLegacyDatetimeCode kann der Unterschied zwischen Client- und Server-Zeitzonen bei Verwendung von Datumsangaben automatisch korrigiert werden. So können Sie nicht unbedingt in jedem Teil Zeitzonen angeben. Die Verwendung des Parameters serverTimeZone ist zwar eine Problemumgehung, und während der Patch veröffentlicht wird, können Sie versuchen, den Code wie ich selbst zu korrigieren.

  • Wenn es sich um eine eigenständige Anwendung handelt, können Sie einfach versuchen, dem Code eine ____-korrigierte Klasse com/mysql/jdbc/TimeUtil hinzuzufügen. Seien Sie dabei vorsichtig Dies kann helfen: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • Wenn es sich um eine Webanwendung handelt, ist die einfachere Lösung die Erstellung einer eigenen Mysql-connector-Java-5.1.37-patched.jar, die die .class direkt in die ursprüngliche jar-Datei einfügt.

26
antgar9

Die Verbindungszeichenfolge sollte folgendermaßen festgelegt werden:

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Wenn Sie die Verbindung in einer xml-Datei definieren (wie persistence.xml, standalone-full.xml usw.), sollten Sie anstelle von &&amp; oder einen CDATA-Block verwenden.

23
Alireza Alallah

Ich habe dieses Problem durch Konfigurieren von MySQL gelöst. 

SET GLOBAL time_zone = '+3:00';

23
Dmitriy Rud

Es funktionierte für mich nur durch Hinzufügen von serverTimeZone = UTC auf application.properties.
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC

15
Ahmed AMMOURI

Ich habe das Platzieren der Verbindungszeichenfolge in der URL behoben

jdbc:mysql://localhost:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Ich habe das gleiche Problem und ich habe es gelöst, füge an meine String-Verbindung nur "? ServerTimezone = UTC" an.

sinossi mein Problem:

Java.sql.SQLException: Der Serverzeitzonenwert 'CEST' wurde nicht erkannt oder repräsentiert mehr als eine Zeitzone. Sie müssen entweder den Server oder den JDBC-Treiber (über die Konfigurationseigenschaft serverTimezone) so konfigurieren, dass ein genauerer Zeitzonenwert verwendet wird, wenn Sie die Zeitzonenunterstützung verwenden möchten.

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 
12

Das obige Programm generiert diesen Zeitzonenfehler.

Nach Ihrem Datenbanknamen müssen Sie Folgendes hinzufügen: ?useTimezone=true&serverTimezone=UTC. Sobald Sie fertig sind, funktioniert Ihr Code einwandfrei.

Viel Glück :)

10
Aathil Ahamed
  1. Ich habe in mysql config file in Abschnitt [mysqld] hinzugefügt

    default_time_zone='+03:00'
    
  2. Und starten Sie den MySQL-Server neu: 

    Sudo service mysql restart
    

Wo +03: 00 meine UTC-Zeitzone.

Pfad zur Konfigurationsdatei auf meinem os ubuntu 16.04:

/etc/mysql/mysql.conf.d/mysqld.cnf

WARNUNG: WENN IHRE ZEITZONE SOMMER UND WINTERZEIT HAT. SIE MÜSSEN UTC IN CONFIG WENN ÄNDERN. ZWEIMAL IM JAHR (ALLGEMEIN) OR CRONTAB MIT Sudo EINSTELLEN.

Meine URL-Jdbc-Verbindung: 

"jdbc:mysql://localhost/Java"
5
Fortran

Führen Sie in der MySQL-Workbench die folgenden SQL-Anweisungen aus:

  1. SET @@ global.time_zone = '+00: 00';
  2. SET @@ session.time_zone = '+00: 00';

überprüfen Sie mit den folgenden SQL-Anweisungen, ob die Werte festgelegt wurden:

SELECT @@ global.time_zone, @@ session.time_zone;

4
toof06

Sie können den MySQL-Connector in der Maven-Abhängigkeit verwenden,

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-Java</artifactId>
        <version>8.0.14</version>
    </dependency>

Dann müssen Sie die richtigen Parameter in der application.properties-Datei einstellen,

spring.datasource.url=jdbc:mysql://localhost:3306/UserReward?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=testuser
spring.datasource.password=testpassword
# MySQL driver
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
4
Arefe

Ich hatte das gleiche Problem, als ich versuchte, mit Spring Boot-Projekt unter Windows zu arbeiten.

Die URL der Datenquelle sollte sein:

spring.datasource.url=jdbc:mysql://localhost/database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

3

Ich benutze mysql-connector-Java-8.0.13 und hatte das gleiche Problem. Ich habe meine Datenbank in der Befehlszeilenkonsole erstellt und dieses Problem durch Verwenden von @Dimitry Rud's solution in der Befehlszeile gelöst:

SET GLOBAL time_zone = '-6:00';

Ich musste nichts neu starten, die Uhrzeit einstellen und sofort meinen Code in Eclipse ausführen, da dies problemlos möglich war.

Der Fehler soll in einer älteren Version behoben sein, aber ich denke, ich habe diese Fehlermeldung erhalten, weil ich diese nicht erstellt habe, nachdem ich die Datenbank in der Konsole erstellt habe. Ich verwende keine Workbench oder eine andere App, um dies und nicht die Konsole zu verwalten.

3
RAdrian

Das hat bei mir funktioniert.

unter DBeaver 6.0: Gehen Sie zu Verbindungseinstellungen> Treibereigenschaften> Serverzeitzone> UTC einstellen.

Außerdem musste im Frühjahr die Bootkonfiguration unter Eigenschaft gesetzt werden.

jdbc: mysql: // localhost: /? serverTimezone = UTC

3
Anil Gowda

Nachdem ich mehrere Beiträge zu diesem Thema gelesen und verschiedene Konfigurationen getestet hatte und basierend auf einigen Erkenntnissen aus diesem Mysql-Bug-Thread habe ich das verstanden:

  • die Server-Zeitzone ist insbesondere für die Konvertierung von in der Datenbank gespeicherten Datumsangaben in die Zeitzone des Anwendungsservers wichtig. Es gibt andere Implikationen, aber dies ist die auffälligste
  • GMT x UTC-Zeitzonensysteme. GMT wurde im späten 19. Jahrhundert konzipiert und kann zwischen Standardzeit und Sommerzeit verschoben werden. Diese Eigenschaft kann dazu führen, dass der Datenbankserver in die Sommerzeit wechselt und die Anwendung dies nicht bemerkt (vielleicht gibt es andere Komplikationen, aber ich habe nicht weiter recherchiert). UTC (basierend auf der Zeit von Portugal im Gegensatz zum GMT in Greenwich) variiert im Zeitverlauf nicht und ist daher stabiler
  • die Definition von serverTimeZone wurde in Version 5.1 der MySQL-Jdbc-Connectors eingeführt. Bis zur Version 8 konnte es mit useLegacyDatetimeCode=true ignoriert werden, wodurch die Anwendung in Verbindung mit useJDBCCompliantTimezoneShift=true die Datenbankzeitzone für jede Verbindung erhält. In diesem Modus werden GMT-Zeitzonen wie "British Summer Time" in das interne Java/JDBC-Format konvertiert. Neue Zeitzonen könnten in einer .properties-Datei definiert werden, z. B. hier
  • Ab der jdbc-Treiberversion 8 wurden der automatische Zeitabgleich (useJDBCCompliantTimezoneShift) und das ältere Zeitformat (useLegacyDatetimeCode) entfernt ( siehe mysql jdbc Connector-Änderungsprotokoll ). Die Einstellung dieser 2 Parameter hat daher keine Auswirkung, da sie vollständig ignoriert werden (neuer Standard ist useLegacyDateTimeCode=false).
  • Auf diese Weise wurde serverTimezone zu obligatorisch, wenn eine der Zeitzonen (Anwendungs-/Datenbankserver) nicht das Format 'UTC + xx' oder 'GMT + xx' hat.
  • Das Festlegen der Serverzeit als UTC (z. B. mit jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC) hat keine Auswirkungen, auch wenn sich Ihre Anwendungs-/Datenbankserver nicht in dieser Zeitzone befinden. Wichtig ist, dass die Verbindungszeichenfolge der Anwendung + die Datenbank mit derselben Zeitzone synchronisiert werden Wörter, Wenn Sie einfach serverTimezone = UTC mit einer anderen Zeitzone auf dem Datenbankserver einstellen, werden alle aus der Datenbank extrahierten Daten verschoben.
  • Die Standard-Zeitzone von MySQL kann mit den Dateien my.ini oder my.cnf (Windows/Linux) auf UTC + 0 festgelegt werden. Fügen Sie dazu die Zeile default-time-zone='+00:00' hinzu (Details in this StackOverflow post ).
  • Datenbanken, die für AWS (Amazon Web Services) konfiguriert sind, erhalten automatisch die Standardzeit UTC + 0 ( siehe AWS-Hilfeseite hier ).
2
epol

@ Ingvars Lösung hat funktioniert. 

String url = "jdbc:mysql://localhost:330/db?serverTimezone="+TimeZone.getDefault().getID()
1
kcmn

Ich bin spät dran, aber wenn Sie sich durch den folgenden Fehler kämpfen und die Datenquelle (javax.sql.DataSource) verwenden:

The server time zone value 'CEST' is unrecognized or represents more than one time zone.

Stellen Sie die folgende Zeile ein, um den Fehler zu beheben:

MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setServerTimezone("UTC");

Ich habe dieses Problem ohne eine einzige Codeänderung gelöst. Gehen Sie einfach zur Systemzeiteinstellung und stellen Sie die Zeitzone ein. In meinem Fall war die Standardzeitzone UTC, die ich in meine lokale Zeitzone geändert habe. Nachdem ich alle Dienste neu gestartet hatte, funktionierte alles für mich. 

1
Nikunj Shroff

Das gleiche Problem hatte ich auch in LibreOffice Base. Also habe ich in der Verbindungszeichenfolge nur eine Zeitzone angegeben, die keine Sommerzeit ist.
 **enter image description here**

Ich habe ohne die "& serverTimezone = MST" ausprobiert, aber das schlug auch aus.

Ich habe auch "& serverTimezone = MDT" ausprobiert und das ist fehlgeschlagen. Aus irgendeinem Grund mag es keine Sommerzeit!

1
GordR

Ich habe folgendes auf meiner Datenbankseite ausgeführt.

mysql> SET @@global.time_zone = '+00:00';

mysql> SET @@session.time_zone = '+00:00';

mysql> SELECT @@global.time_zone, @@session.time_zone;

Ich verwende die Serverversion 8.0.17 - MySQL Community Server - GPL

quelle: https://community.Oracle.com/thread/4144569?start=0&tstart=

1
Vishrant

In meinem Fall war es eine Testumgebung, und ich musste eine vorhandene Anwendung so einrichten, dass sie ohne Konfigurationsänderungen und wenn möglich ohne MySQL-Konfigurationsänderungen funktioniert. Ich konnte das Problem beheben, indem ich dem @ vinnyjames-Vorschlag folgte und die Server-Zeitzone in UTC änderte :

ln -sf /usr/share/zoneinfo/UTC /etc/localtime
service mysqld restart

Das war genug für mich, um das Problem zu lösen.

0
Dmitriusan

Stimmen Sie der @ bluecollarcoder-Antwort zu, es ist jedoch besser, am Ende der VerbindungszeichenfolgeTimeZone.getDefault().getID();zu verwenden:

"jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=" + TimeZone.getDefault().getID();  

In diesem Fall wird der Parameter Timezone abhängig von der Zeitzone des lokalen Computers automatisch aktualisiert.

0
Yerbol

Alles was wir brauchen, um das Problem mit serverTimezone zu beheben:

String url = "jdbc:mysql://localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()
0
Ingvar