Bug #87075 ClusterJ ClusterJDatastoreException.getCode() returns 0 instead of 630
Description:
The com.mysql.clusterj.ClusterJDatastoreException.getCode() method (see: https://dev.mysql.com/doc/ndbapi/en/mccj-clusterj-clusterjdatastoreexception.html#mccj-clu...) should get the code for an error, as listed at https://dev.mysql.com/doc/ndbapi/en/ndb-error-codes-single.html
However, we find that when a 630 should result, we instead see a 0. The message string still contains the error code, and we are currently checking the substring as a workaround, but it's hacky and unreliable (e.g. the string contains that number for a different reaso).
Other getCode() results appear to work, in particular we tested 159 and 121. We find that the message strings look different in the work / not work cases; log entries from local testing:
ClusterJDatastoreException getCode => 241 for message => Error in NdbJTie: returnCode -1, code 241, mysqlCode 159, status 2, classification 4, message Invalid schema object version .
ClusterJDatastoreException getCode => 0 for message => Datastore exception. Return code: -1 Error code: 630 MySQL code: 121 Status: 2 Classification: 3 Message: NdbRecordOperationImpl for table notification_metadata
ClusterJDatastoreException getCode => 893 for message => Error in NdbJTie: returnCode -1, code 893, mysqlCode 121, status 2, classification 3, message Constraint violation e.g. duplicate value in unique index ndb_tiledb/def/user_identification/external_user_idx$unique.
Though it sometimes works, we're extremely hesitant to consider any of this at all reliable. We're stuck between using a method that we have observed not functioning correctly, doing string manipulation, or some combination thereof.
How to repeat:
We're using NDB database and Jar versions 7.5.5 and mysql:mysql-connector-java:6.0.6 (https://mvnrepository.com/artifact/mysql/mysql-connector-java/6.0.6).
Given a simple schema like:
CREATE TABLE example_table (
mykey INT,
PRIMARY KEY(mykey)
) engine=ndb;
and its ClusterJ annotated interface
@PersistenceCapable(table = "example_table")
public interface IExample {
@PrimaryKey
@Column(name = "mykey")
int getMyKey();
void setMyKey(int myKey);
}
one can run the following code:
// clusterJSession setup first
final IExample example = clusterJSession.newInstance(IExample.class);
example.setMyKey(1);
clusterJSession.persist(example);
clusterJSession.persist(example); // this will cause a constraint violation when committed
try {
clusterJSession.flush();
} catch (ClusterJDatastoreException e) {
System.out.println(String.format("---\ncode: %s | mysqlCode: %s | status: %s | classification: %s\nMessage:\n%s\n---",
e.getCode(), e.getMysqlCode(), e.getStatus(), e.getClassification(), e.getMessage()));
}
and find that the first four getter methods that return ints all return 0 rather than the values they should, as are visible from the getMessage() call. In particular, I got the following output:
---
code: 0 | mysqlCode: 0 | status: 0 | classification: 0
Message:
Datastore exception. Return code: -1 Error code: 630 MySQL code: 121 Status: 2 Classification: 3 Message: NdbRecordOperationImpl for table example_table
Datastore exception. Return code: -1 Error code: 630 MySQL code: 121 Status: 2 Classification: 3 Message: NdbRecordOperationImpl for table example_table
---
but expected the first line to be "code: 630 | mysqlCode: 121 | status: 2 | classification: 3".
Thrown stack trace:
Caused by: com.mysql.clusterj.ClusterJDatastoreException: Datastore exception. Return code: -1 Error code: 630 MySQL code: 121 Status: 2 Classification: 3 Message: NdbRecordOperationImpl for table example_table
Datastore exception. Return code: -1 Error code: 630 MySQL code: 121 Status: 2 Classification: 3 Message: NdbRecordOperationImpl for table example_table
at com.mysql.clusterj.tie.ClusterTransactionImpl.performPostExecuteCallbacks(ClusterTransactionImpl.java:590)
at com.mysql.clusterj.tie.ClusterTransactionImpl.executeNoCommit(ClusterTransactionImpl.java:207)
at com.mysql.clusterj.core.SessionImpl.executeNoCommit(SessionImpl.java:1498)
at com.mysql.clusterj.core.SessionImpl.executeNoCommit(SessionImpl.java:1511)
at com.mysql.clusterj.core.SessionImpl.flush(SessionImpl.java:1424)
at com.mysql.clusterj.core.SessionImpl.flush(SessionImpl.java:1432)
at com.example.Example.repro(Example.java:30)
at com.example.Example.lambda$main$0(Example.java:16)
Suggested fix:
Remove the constructors:
ClusterJDatastoreException(String msg)
ClusterJDatastoreException(String msg, Throwable cause)
ClusterJDatastoreException(Throwable cause)
and make the relevant variables final so that they cannot accidentally not be initialized.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.039 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.