Description:
When :replication is included in the connection string then ResultSet.updateBlob fails with a ClassCastException like the following:
```
Exception in thread "main" java.lang.ClassCastException: class com.sun.proxy.$Proxy3 cannot be cast to class com.mysql.cj.jdbc.ClientPreparedStatement (com.sun.proxy.$Proxy3 and com.mysql.cj.jdbc.ClientPreparedStatement are in unnamed module of loader 'app')
at com.mysql.cj.jdbc.result.UpdatableResultSet.syncUpdate(UpdatableResultSet.java:1130)
at com.mysql.cj.jdbc.result.UpdatableResultSet.updateBlob(UpdatableResultSet.java:1270)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.mysql.cj.jdbc.ha.MultiHostConnectionProxy$JdbcInterfaceProxy.invoke(MultiHostConnectionProxy.java:107)
at com.sun.proxy.$Proxy5.updateBlob(Unknown Source)
at com.raveu.test.Test.writeToFile(Test.java:29)
at com.raveu.test.Test.main(Test.java:42)
```
Running through the error in the debugger I have traced the problem to:
```
MultiHostMySQLConnection.clientPrepareStatement(String)
```
Notably without :replication: in the connection string ConnectionImpl is used directly and there is no error.
I found this in Apache ArtemisMQ and was able to reproduce with an example program below
How to repeat:
Create a table in a database in mysql:
```
CREATE TABLE `blob_test` (
`id` bigint NOT NULL,
`data` longblob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
```
Then run the following test program (adjust the connection string for your database):
```
package com.raveu.test;
import java.sql.*;
public class Test {
public void writeToFile() throws SQLException {
byte data[] = {(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef};
Connection connection = DriverManager.getConnection("jdbc:mysql:replication://localhost,localhost/DbRave?user=rave&password=rave");
connection.setAutoCommit(false);
try (PreparedStatement appendToLargeObject = connection.prepareStatement(
"SELECT id, data FROM blob_test WHERE id=? FOR UPDATE",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE)) {
appendToLargeObject.setLong(1, 1L);
try (ResultSet rs = appendToLargeObject.executeQuery()) {
if (rs.next()) {
Blob blob = rs.getBlob(1);
if (blob == null) {
blob = connection.createBlob();
}
blob.truncate(0);
blob.setBytes(1, data);
rs.updateBlob(1, blob);
rs.updateRow();
}
connection.commit();
} catch (SQLException e) {
connection.rollback();
throw e;
}
}
}
public static void main(String args[]) throws Exception {
var t = new Test();
t.writeToFile();
}
}
```