web-dev-qa-db-ja.com

MySQL JDBC Driver 5.1.33 - タイムゾーンの問題

いくつかの背景:

Tomcat 7上でJava 1.6 Webアプリケーションを実行しています。データベースはMySQL 5.5です。以前は、Mysql JDBCドライバ5.1.23を使用してDBに接続していました。すべてうまくいった。私は最近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.

なんでこんなことが起こっているの?

220
bluecollarcoder

どうやら、MySQL JDBCドライバのバージョン5.1.33をUTCタイムゾーンで動作させるには、接続文字列でserverTimezoneを明示的に指定する必要があります。

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

私はMySQLを設定することでこの問題を解決しました。

SET GLOBAL time_zone = '+3:00';

47
Dmitriy Rud

Mavenを使用している場合は、pom.xmlに別のMySQLコネクタバージョンを設定することができます(同じエラーが発生したため、6.0.2から5.1.39に変更しました)。

<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>

pom.xmlファイルを保存すると、Mavenは自動的にプロジェクトを再ビルドします。

これはバージョン5.1.33から5.1.37へのmysql-connector-Javaのバグです。ここで報告しました: http://bugs.mysql.com/bug.php?id=79343

編集:これはmysql-connector-Java 5.1.39から修正されました

LoadTimeZoneMappingsメソッドのTimeUtilクラスのタイプミスで、NPEの/com/mysql/jdbc/TimeZoneMapping.propertiesファイルが発生しました。コードを見ると、ファイルはTimeZoneではなくTimeUtilクラスローダー内にあるはずです。

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

パラメータ useLegacyDatetimeCode を使用すると、日付を使用するときにクライアントとサーバーのタイムゾーンの違いを自動的に修正できます。そのため、各部分でタイムゾーンを指定する必要がなくなります。 serverTimeZone パラメータを使用するのは回避策ですが、その間にパッチがリリースされますが、私が行ったように自分でコードを修正することをお勧めします。

  • スタンドアロンアプリケーションの場合は、コードに訂正済みのcom/mysql/jdbc/TimeUtilクラスを追加し、jarの読み込み順序に注意してください。これは役立ちます: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • それがWebアプリケーションであるならば、もっと簡単な解決策はあなた自身のmysql-connector-Java-5.1.37-patched.jarを作成することです。元のjarファイルに直接.classを代入すること。

29
antgar9

接続文字列は次のように設定します。

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

接続をxmlファイル(persistence.xmlstandalone-full.xmlなど)で定義している場合は、&の代わりに&amp;を使用するかCDATAブロックを使用してください。

28
Alireza Alallah

URLの下に接続文字列を入れて解決しました

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

このトピックに関するいくつかの投稿を読んだ後、さまざまな設定をテストし、 このmysqlバグスレッド から得られたいくつかの洞察に基づいて、これが私が理解したことです。

  • サーバーのタイムゾーンは、データベースに格納されている日付をアプリケーションサーバーのタイムゾーンに変換するために特に重要です。他の影響がありますが、これは最も顕著なものです
  • GMT x UTCタイムゾーンシステムGMTは19世紀後半に考案されたもので、標準時と夏時間の間で変更することができます。このプロパティは、データベース・サーバは、サマータイムに移行し、アプリケーションが(おそらく他の合併症があるが、私はさらに調査していない)、それを気づかないような状況につながる可能性があります。 UTCは経時的に変化しません(それは常に0°経度で平均太陽時の約1秒以内です)。
  • serverTimeZone定義は、mysql JDBCコネクタバージョン5.1以降で導入されました。バージョン8まではuseLegacyDatetimeCode=trueで無視することができました。これはuseJDBCCompliantTimezoneShift=trueと組み合わせてアプリケーションがすべての接続でデータベースのタイムゾーンを取得するようにします。このモードでは、 'British Summer Time'などのGMTタイムゾーンは内部のJava/JDBCフォーマットに変換されます。新しいタイムゾーンは、 this one などの.propertiesファイルで定義できます。
  • Jdbcドライバのバージョン8から、自動時間一致(useJDBCCompliantTimezoneShift)とレガシータイムフォーマット(useLegacyDatetimeCode)が削除されました( mysql jdbcコネクタchangelog を参照)。したがって、これら2つのパラメータを設定しても、それらは完全に無視されるので効果がありません(新しいデフォルトはuseLegacyDateTimeCode=false)。
  • このように設定serverTimezone必須 いずれかのタイムゾーン(アプリケーション/データベースサーバー)が 'UTC + xx'または 'GMT + xx'の形式になっていない場合
  • サーバー時間をUTCに設定することによる影響はありません(たとえば、アプリケーション/データベースサーバーがこのタイムゾーンにない場合でもjdbc:mysql://localhost:3306/myschema?serverTimezone=UTCを使用します)。重要なのは、アプリケーション接続文字列+データベースを同じタイムゾーンと同期させることです。 データベースサーバー上で異なるタイムゾーンを指定してserverTimezone = UTCを設定すると、データベースから抽出された日付がシフトされます
  • MySQLのデフォルトタイムゾーンは、default-time-zone='+00:00'という行を追加することで、my.iniファイルまたはmy.cnfファイル(それぞれwindows/linux)でUTC + 0に設定できます(詳細は このStackOverflow post
  • AWS(Amazon Webサービス)で設定されたデータベースには、UTC + 0のデフォルト時間( ここのAWSヘルプページを参照 )が自動的に割り当てられます
17
epol

私は同じ問題を抱えていて、私はそれが私の文字列接続に "?serverTimezone = UTC"だけを追加することを解決しました。

sinossi私の問題:

Java.sql.SQLException:サーバーのタイムゾーン値 'CEST'が認識されないか、複数のタイムゾーンを表しています。タイムゾーンサポートを利用する場合は、より詳細なタイムゾーン値を使用するように(serverTimezone構成プロパティを介して)サーバーまたはJDBCドライバを構成する必要があります。

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 
16
  1. Mysqlの設定ファイルのセクション[mysqld]に追加しました

    default_time_zone='+03:00'
    
  2. そしてmysqlサーバーを再起動します。

    Sudo service mysql restart
    

UTCのタイムゾーンは+03:00です。

私のos ubuntu 16.04上の設定ファイルへのパス:

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

警告:あなたのタイムゾーンに夏と冬の時間がある場合は、時間を変更する場合はUTCを変更してください。年に2回(通常)OR CRONTABでSUDOを設定してください

私のURL DBC接続:

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

上記のプログラムは、そのタイムゾーンエラーを生成します。

データベース名の後に、?useTimezone=true&serverTimezone=UTCを追加する必要があります。完了したら、コードは正常に機能します。

幸運を祈る:)

10
Aathil Ahamed

serverTimezoneで問題を解決するために必要なすべてのもの:

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

Application.propertiesにserverTimeZone = UTCを追加するだけでうまくいきました。
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC

6
Ahmed AMMOURI

私は mysql-connector-Java-8.0.13を使用しています 同じ問題がありました。データベースをコマンドラインコンソールで作成し、コマンドラインで @Dimitry Rudの solutionを使用してこの問題を解決しました。

SET GLOBAL time_zone = '-6:00';

私は何も再起動する必要はなく、時間を設定してすぐにEclipseでコードを実行しましたが、問題なく接続できました。

このバグは古いバージョンで修正されるはずですが、コンソールでデータベースを作成した後に設定しなかったため、このエラーが発生したと思います。これを管理するために、コンソールではなくワークベンチも他のアプリも使用していません。

4
RAdrian

Mysqlワークベンチから、以下のSQLステートメントを実行します。

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

次のSQL文を使用して、値が設定されているかどうかを確認します。

SELECT @@ global.time_zone、@@ session.time_zone;

4
toof06

Windowsでスプリングブートプロジェクトを使用しようとすると、同じ問題が発生しました。

データソースのURLは次のとおりです。

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

3

MySQLコネクタはMavenの依存関係で使用できます。

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

それならapplication.propertiesファイルに正しいパラメータを設定する必要があります。

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
3
Arefe

@ Ingvarの解決策はうまくいきました。

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

私は遅れています、しかし、あなたが以下のエラーを通して苦労していて、データソース(javax.sql.DataSource)を使っているなら:

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

次の行を設定してエラーを取り除きます。

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

私はこの問題をコードを変更することなく解決しました。システムの時間設定を変更してタイムゾーンを設定するだけです。私の場合、デフォルトのタイムゾーンはUTCでしたが、これをローカルタイムゾーンに変更しました。すべてのサービスを再開した後、すべてがうまくいった。

1
Nikunj Shroff

私はLibreOffice Baseでもまったく同じ問題を抱えていました。そのため、接続文字列に「夏時間以外のゾーン」を指定しただけです。
**enter image description here**

私は を使わずに "&serverTimezone = MST"を試しましたが、それも失敗しました。

私も "&serverTimezone = MDT"を試してみましたが失敗しました。なんらかの理由で夏時間は好きではありません。

1
GordR

私はデータベース側で次を実行しました。

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

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

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

サーバーバージョン8.0.17を使用しています-MySQL Community Server-GPL

ソース: https://community.Oracle.com/thread/4144569?start=0&tstart=

1
Vishrant

私の場合はテスト環境だったので、既存のアプリケーションを設定変更なしで、そして可能であればMySQL設定変更なしで動作させる必要がありました。 @vinnyjamesの提案とサーバーのタイムゾーンをUTCに変更を実行することで問題を解決できました。

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

それをすることは私が問題を解決するのに十分だった。

0
Dmitriusan

@bluecollarcoderの回答に同意しますが、接続文字列の最後にTimeZone.getDefault().getID();を使用することをお勧めします。

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

この場合、Timezoneパラメータはローカルマシンのタイムゾーンに応じて自動的に更新されます。

0
Yerbol

これは私のために働きました。

dBeaver 6.0の場合:[接続設定]> [サーバータイムゾーン]> [UTCの設定]に移動します。

0
Anil Gowda