If you recently upgraded your Java application's JDBC driver to MySQL Connector/J 9.5.0 while running against OceanBase CE (MySQL Mode), you might have encountered a frustrating bug: standard Statement queries execute normally and return data, but PreparedStatement queries silently return empty result sets (zero rows) without throwing an exception.

The Root Cause: Binary Protocol Incompatibility

This issue stems from how MySQL Connector/J handles server-side prepared statements versus client-side prepared statements when communicating with non-native MySQL engines like OceanBase.

When useServerPrepStmts=true is set in your JDBC connection URL, Connector/J uses the MySQL binary protocol (COM_STMT_PREPARE and COM_STMT_EXECUTE) instead of sending plain text SQL queries. Starting in version 9.5.0, Oracle updated Connector/J's internal protocol handling, strict type checking, and result-set metadata decoding for binary protocol responses.

OceanBase's MySQL protocol emulation layer (specifically around MySQL 5.7/8.0 compatibility modes) has subtle differences in how it encodes binary result packets for COM_STMT_EXECUTE compared to official MySQL Server versions. These protocol differences cause Connector/J 9.5.0 to misinterpret the binary response payload from OceanBase as an EOF/ empty set marker, even though the data was transmitted by the server.

How to Fix the Issue

Depending on your architecture and requirements, there are three primary solutions to resolve this behavior.

Solution 1: Disable Server-Side Prepared Statements (Recommended Workaround)

The simplest immediate fix without changing drivers or rolling back is to disable server-side prepared statements in your JDBC URL. This forces Connector/J to emulate prepared statements on the client side using text protocol (standard COM_QUERY), which works reliably across all versions of OceanBase.

Update your JDBC connection string as follows: