【1】MySQLのJDBCドライバを上げたらエラー「The server time zone value」になる
現象詳細
MySQLのJDBCドライバを v5.1.46 から v8.0.11 にあげたとこと、 以下の「エラー内容」になる
build.gradle
修正前 (現象発生なし)dependencies { // MySQL compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46' }修正後 (現象発生あり)
dependencies { // MySQL compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.11' }
エラー内容
java.sql.SQLException: The server time zone value '???? (?W????)' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:127) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:87) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:61) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:71) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:444) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) at java.sql.DriverManager.getConnection(Unknown Source) at java.sql.DriverManager.getConnection(Unknown Source) at com.sample.db.SelectDemo.main(SelectDemo.java:15) Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '???? (?W????)' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:59) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:83) at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:128) at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2201) at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2225) at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1391) at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:993) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:852) ... 6 more
サンプル
修正前import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SelectDemo { public static void main(String[] args) throws ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); try ( Connection connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/sampledb", "root", "password"); PreparedStatement preparedStatement = connection .prepareStatement("SELECT * FROM person");) { ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { System.out.println(String.format("id=%s, name=%s", resultSet.getString("id"), resultSet.getString("name"))); } } catch (SQLException ex) { ex.printStackTrace(); } } }
解決案
* 「serverTimezone」を指定する => 「serverTimezone=JST」みたいな。
サンプル
修正後import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SelectDemo { public static void main(String[] args) throws ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); try ( Connection connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/sampledb?serverTimezone=JST", "root", "password"); // ★ここ★ PreparedStatement preparedStatement = connection .prepareStatement("SELECT * FROM person");) { ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { System.out.println(String.format("id=%s, name=%s", resultSet.getString("id"), resultSet.getString("name"))); } } catch (SQLException ex) { ex.printStackTrace(); } } }
参考文献
https://www.nakamuri.info/mw/index.php/Mysql-connector-java_%E3%81%AE%E3%83%90%E3%82%B0%E3%81%A7_Java%E3%81%8B%E3%82%89MySQL%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84
【2】 MySQLのJDBCドライバを上げたらエラー「class `com.mysql.jdbc.Driver'. This is deprecated.」って言われる
ログ内容
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
原因
英語読めばわかるが...Class.forName("com.mysql.jdbc.Driver"); の指定が古いらしい。
解決案
[1] Class.forName("com.mysql.cj.jdbc.Driver"); にする 又は [2] Class.forName("com.mysql.jdbc.Driver"); の行を消す(自動的にロードしてくれるらしいので)