Description:
table with a datetime column, and set value between 1900-01-01 08:00:00
and 1900-01-01 08:05:00;
map this column into a java.sql.TimeStamp java type, bollow exception throws:
Caused by: java.lang.IllegalArgumentException: MINUTE: 5 -> 10
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2825)
at java.util.Calendar.updateTime(Calendar.java:3395)
at java.util.Calendar.getTimeInMillis(Calendar.java:1782)
at com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromDatetime(SqlTimestampValueFactory.java:191)
How to repeat:
// create table sql:
CREATE TABLE `person` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'name',
`age` int DEFAULT NULL COMMENT 'age',
`birth` datetime DEFAULT NULL COMMENT 'birth',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='for TEST';
// insert data
insert into person (id, name, age, birth) values (1, 'tom', 18, '1900-01-01 08:05:00');
// select in java with connector/j
public class Mysql8BugTestTest {
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (Exception e) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception t) {
throw new RuntimeException(t);
}
}
}
public static final String MYSQL_URL_FORMAT = "jdbc:mysql://%s/%s?useSSL=false&characterEncoding=UTF-8";
@Test
public void mysql8SocketTimeoutTest() throws SQLException {
try(Connection connection = getConnection()) {
try(Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("select * from person where id =1;");
while(resultSet.next()) {
Timestamp birth = resultSet.getTimestamp("birth");
}
// Ignore for Processing of ResultSet
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Connection getConnection() throws SQLException {
return DriverManager.getConnection(String.format(Constants.MYSQL_URL_FORMAT, "ip:port", "dbname"), "uid", "pwd");
}
}
Suggested fix:
we replay the same select with connector/j 5.1.48 and it worked well, so figured out difference between connector/j 5.1.48 and 8.0.33;
in 8.0.33 src/main/core-impl/java/com/mysql/cj/result/SqlTimestampValueFactory.java
c = Calendar.getInstance(this.defaultTimeZone, Locale.US);
c.setLenient(false);
if remove
c.setLenient(false);
it will be fine.
Description: table with a datetime column, and set value between 1900-01-01 08:00:00 and 1900-01-01 08:05:00; map this column into a java.sql.TimeStamp java type, bollow exception throws: Caused by: java.lang.IllegalArgumentException: MINUTE: 5 -> 10 at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2825) at java.util.Calendar.updateTime(Calendar.java:3395) at java.util.Calendar.getTimeInMillis(Calendar.java:1782) at com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromDatetime(SqlTimestampValueFactory.java:191) How to repeat: // create table sql: CREATE TABLE `person` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'name', `age` int DEFAULT NULL COMMENT 'age', `birth` datetime DEFAULT NULL COMMENT 'birth', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='for TEST'; // insert data insert into person (id, name, age, birth) values (1, 'tom', 18, '1900-01-01 08:05:00'); // select in java with connector/j public class Mysql8BugTestTest { static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (Exception e) { try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception t) { throw new RuntimeException(t); } } } public static final String MYSQL_URL_FORMAT = "jdbc:mysql://%s/%s?useSSL=false&characterEncoding=UTF-8"; @Test public void mysql8SocketTimeoutTest() throws SQLException { try(Connection connection = getConnection()) { try(Statement statement = connection.createStatement()) { ResultSet resultSet = statement.executeQuery("select * from person where id =1;"); while(resultSet.next()) { Timestamp birth = resultSet.getTimestamp("birth"); } // Ignore for Processing of ResultSet } } catch (Exception e) { e.printStackTrace(); } } private Connection getConnection() throws SQLException { return DriverManager.getConnection(String.format(Constants.MYSQL_URL_FORMAT, "ip:port", "dbname"), "uid", "pwd"); } } Suggested fix: we replay the same select with connector/j 5.1.48 and it worked well, so figured out difference between connector/j 5.1.48 and 8.0.33; in 8.0.33 src/main/core-impl/java/com/mysql/cj/result/SqlTimestampValueFactory.java c = Calendar.getInstance(this.defaultTimeZone, Locale.US); c.setLenient(false); if remove c.setLenient(false); it will be fine.