Bug #81202 ResultSetImpl.getObject throws NullPointerException when field is null
Submitted: 26 Apr 2016 14:50 Modified: 9 Mar 2017 4:17
Reporter: IT MicroWorld Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:6.0.2 OS:Any
Assigned to: CPU Architecture:Any

[26 Apr 2016 14:50] IT MicroWorld
Description:
The new java.time types in Java 8 are retrieved from the database with ResultSet.getObject() (there are no specific methods for those new types in JDBC).

When doing so with Connector/J 6.0.2 and the content of the field is null, a NullPointerException is thrown instead of returning null value.

The affected types are LocalDate, LocalDateTime, LocalTime, OffsetDateTime and OffsetTime.

How to repeat:
// Select a null date field from the database then:
resultSet.getObject(columnIndex, LocalDate.class);
// A NullPointerException is thrown.

Suggested fix:
Do a null check in ResultSetImpl.getObject(int columnIndex, Class<T> type) for the affected types or handle the new types with a proper ValueFactory like for the other types instead of going through an intermediate type.

For instance for LocalDate, line 1512 could be replaced with something like:
Date date = getDate(columnIndex);
return (T) (date == null ? null : date.toLocalDate());
[27 Apr 2016 9:00] Chiranjeevi Battula
Hello IT Team,

Thank you for the bug report.
I tried to reproduce the issue at my end using Java 8 and MySQL Connector / J 6.0.2 but not seeing any issues in selecting date values with null.
Could you please provide repeatable test case (create table statements, MySQL version, sample test case, etc. - please make it as private if you prefer) to confirm this issue at our end?

Thanks,
Chiranjeevi.
[27 Apr 2016 9:26] IT MicroWorld
Hi Chiranjeevi,

Thanks for your reply, here is a quick test case:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;

public class Bug81202 {
  public static void main(final String... args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
    Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
    final Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testschema?useSSL=false", "root", "");

    final Statement statement = connection.createStatement();
    statement.execute("CREATE TABLE test (id INT unsigned NOT NULL, value_date DATE)");
    statement.executeUpdate("INSERT INTO test VALUES (1, '2016-04-27')");
    statement.executeUpdate("INSERT INTO test VALUES (2, NULL)");
    final ResultSet resultSet = statement.executeQuery("SELECT * FROM test");

    while (resultSet.next()) {
      System.out.println(resultSet.getLong(1) + ": " + resultSet.getObject(2, LocalDate.class));
    }

    resultSet.close();
    statement.close();
  }
}

When I run this code I get the following output:

1: 2016-04-27
Exception in thread "main" java.lang.NullPointerException
	at com.mysql.cj.jdbc.ResultSetImpl.getObject(ResultSetImpl.java:1512)
	at org.microworld.drupal.Bug81202.main(Bug81202.java:22)

Let me know if you need more information.

Laurent.
[27 Apr 2016 9:46] Chiranjeevi Battula
Hello IT Team,

Thank you for your feedback and test case.
Verified this behavior on MySQL Connector / J 6.0.2.

Thanks,
Chiranjeevi.
[27 Apr 2016 9:46] Chiranjeevi Battula
run:
1: 2016-04-27
Exception in thread "main" java.lang.NullPointerException
	at com.mysql.cj.jdbc.ResultSetImpl.getObject(ResultSetImpl.java:1512)
	at javaapplication3.Bug81202.main(Bug81202.java:21)
C:\Users\cbattula\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)
[22 May 2016 1:00] Nazar Ostryzhniuk
I use version 5.1.39

The fix should go here: com.mysql.jdbc.JDBC42ResultSet#getObject

I just put next 3 lines at the beginning of the method:
if (getObject(columnIndex) == null) {
    return null;
} 
and created my own copy of the file in the project.

I beleave that more sophisticated solution exists, as here: com.mysql.jdbc.ResultSetImpl#getObject(int)

An issue is very easy to fix but very annoying for developers, I hope it will be fixed ASAP, thank you.
[3 Nov 2016 6:12] Chiranjeevi Battula
http://bugs.mysql.com/bug.php?id=83662 marked as duplicate of this one.
[3 Nov 2016 7:49] Maxim Solodovnik
Copied from http://bugs.mysql.com/bug.php?id=83662 (for some unknown reason marked as duplicate of this issue)

VERSION AFFECTED 5.1.40, works as expected in 5.1.39 and earlier

NullPointerException is thrown when NULL Boolean value is being read from MySql DB.

Here is the stack trace:

java.lang.NullPointerException
     at com.mysql.jdbc.ResultSetImpl.getNumericRepresentationOfSQLBitType(ResultSetImpl.java:4936)
     at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2479)

How to repeat:
Create NULLABLE BIT(1) column in DB table
Set value to NULL

try to read it with Mysql Connector/J 5.1.40

Suggested fix:
Null check in com.mysql.jdbc.ResultSetImpl.getInt line 2472
Need to be placed BEFORE getNumericRepresentationOfSQLBitType call
[9 Mar 2017 4:17] Daniel So
Posted by developer:
 
Added the following entry to the Connector/J 6.0.6 changelog:

"A NullPointerException was thrown when a NULL object of any of the classes defined in the java.time package was retried by the ResultSet.getObject() method."