Bug #104349 com.mysql.cj NPE
Submitted: 18 Jul 2021 17:00 Modified: 5 Apr 2022 22:32
Reporter: Kevin Huang Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:8.0.25 OS:Any
Assigned to: CPU Architecture:Any
Tags: npe

[18 Jul 2021 17:00] Kevin Huang
Description:
My JPA/Hibernate with MySQL/J 8.0.25 works ok.
But today I turned on trace logging , want to inspect the binding value.
I set logback.xml <root level="TRACE"> and observed the test case.
And I noticed it throw exception :

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
...

Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because "this.value" is null
	at com.mysql.cj.ServerPreparedQueryBindValue.toString(ServerPreparedQueryBindValue.java:156)
	at com.mysql.cj.ServerPreparedQueryBindValue.toString(ServerPreparedQueryBindValue.java:134)
	at com.mysql.cj.ServerPreparedQueryBindValue.getByteValue(ServerPreparedQueryBindValue.java:488)
	at com.mysql.cj.AbstractPreparedQuery.asSql(AbstractPreparedQuery.java:188)
	at com.mysql.cj.jdbc.ClientPreparedStatement.asSql(ClientPreparedStatement.java:271)
	at com.mysql.cj.jdbc.ServerPreparedStatement.toString(ServerPreparedStatement.java:160)
	at com.zaxxer.hikari.pool.ProxyStatement.toString(ProxyStatement.java:53)
	at java.base/java.util.Formatter$FormatSpecifier.printString(Formatter.java:3031)
	at java.base/java.util.Formatter$FormatSpecifier.print(Formatter.java:2908)
	at java.base/java.util.Formatter.format(Formatter.java:2673)
	at java.base/java.util.Formatter.format(Formatter.java:2609)
	at java.base/java.lang.String.format(String.java:3292)
	at org.jboss.logging.Slf4jLocationAwareLogger.doLogf(Slf4jLocationAwareLogger.java:81)
	at org.jboss.logging.Logger.logf(Logger.java:2398)

How to repeat:
@Entity
data class Relation(
  @ElementCollection(fetch = FetchType.EAGER , targetClass = String::class)
  @MapKeyColumn(name = "locale")
  @Column(name = "value")
  @JoinTable(name = "RelationName", joinColumns = [JoinColumn(name = "relation_id")])
  val langMap: MutableMap<Locale, String> = mutableMapOf()
)

interface RelationDao : JpaRepository<Relation, Long>

  @Test
  fun testMultiValue() {

    val enValue = "value1"
    val zhValue = "value2"
    val rel = relationDao.save(
      Relation(
        mutableMapOf(
          Locale.ENGLISH to enValue,
          Locale.TAIWAN to zhValue
        )
      )
    )
  }

It will fail. But if the map contains only one pair of key-value , it will be OK.

If I set the log level to debug or info , it will be OK.
Only 'trace' will be able to observe the binding value , and trigger this exception.

Suggested fix:
com.mysql.cj.ServerPreparedQueryBindValue.java , line 156

from :
return String.valueOf(((Long) this.value).longValue());
Please add null check

other cases the same
[28 Jul 2021 15:59] Filipe Silva
Hi Kevin,

Thank you for your interest in MySQL and Connector/J.

I'm unable to reproduce this. Can you please provide a test case written in Java and without using Hibernate? Thanks!
[28 Jul 2021 16:13] Filipe Silva
Hi again,

I may not need another test case after all. But, can you please show us the non sensitive connection properties are you setting in your connection string? 

I'd say you are setting at least `useServerPrepStmts=true` and `cachePrepStmts=true`. Can you please try with `cachePrepStmts=false` and tell us the result?

Thanks.
[29 Aug 2021 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[12 Nov 2021 10:57] Filipe Silva
NPE verified.
[5 Apr 2022 22:32] Daniel So
Posted by developer:
 
Added the following entry to the Connector/J 8.0.29 changelog: 

"When the Connector/J logger level was at TRACE, a null bind value for a PreparedStatement resulted in a NullPointerException when the logger tried to read the value. This patch added a null check to avoid the exception to be thrown under the situation."
[28 Mar 2023 11:12] Stefan Heisl
This seems to be a bug report for a NullPointerException issue in com.mysql.cj, which occurred when the logging level was set to TRACE and the prepared statement had a null bind value. The suggested fix is to add a null check in com.mysql.cj.ServerPreparedQueryBindValue.java. The developer verified the issue and fixed it in Connector/J 8.0.29. More information about this error: https://incrediblethings.com/work/logistics-software-benefits-how-to-boost-your-small-busi...