sandynz opened a new issue, #37282:
URL: https://github.com/apache/shardingsphere/issues/37282
Related code:
```
HashModShardingAlgorithm.java
private long hashShardingValue(final Object shardingValue) {
return Math.abs((long) shardingValue.hashCode());
}
```
### Possible issue 1
`java.lang.Number` sub-classes might have different `hashCode()`
implementation, e.g.
```
println("Integer.valueOf(-1).hashCode(): " + Integer.valueOf(-1).hashCode())
println("Long.valueOf(-1).hashCode(): " + Long.valueOf(-1).hashCode())
println("BigInteger.valueOf(-1).hashCode(): " +
BigInteger.valueOf(-1).hashCode())
-- result
Integer.valueOf(-1).hashCode(): -1
Long.valueOf(-1).hashCode(): 0
BigInteger.valueOf(-1).hashCode(): -1
```
Eexample table: `t_order`.
Sharding rule:
```
rules:
- !SHARDING
autoTables:
t_order:
actualDataSources: ds_0,ds_1
shardingStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: auto_mod
keyGenerateStrategy:
column: user_id
keyGeneratorName: snowflake
shardingAlgorithms:
auto_mod:
type: HASH_MOD
props:
sharding-count: 2
keyGenerators:
snowflake:
type: SNOWFLAKE
```
Insert record with Integer sharding key value, then query with Long sharding
key value, ResultSet return empty result.
Test code:
```
@Test
void assertHashModSetLongOnIntColumnWorks() throws SQLException {
try (Connection connection =
DriverManager.getConnection("jdbc:shardingsphere:classpath:config/driver/foo-driver-fixture.yaml"))
{
assertThat(connection, isA(ShardingSphereConnection.class));
try (Statement statement = connection.createStatement()) {
statement.execute("DROP TABLE IF EXISTS t_order");
statement.execute("CREATE TABLE t_order (order_id INT
PRIMARY KEY, user_id INT)");
}
int value = -1;
try (PreparedStatement preparedStatement =
connection.prepareStatement("INSERT INTO t_order (order_id, user_id) VALUES (?,
?)")) {
preparedStatement.setObject(1, value); // Insert with
Integer value
preparedStatement.setObject(2, 101);
int updatedCount = preparedStatement.executeUpdate();
assertThat(updatedCount, is(1));
}
try (PreparedStatement preparedStatement =
connection.prepareStatement("SELECT * FROM t_order WHERE order_id = ?")) {
preparedStatement.setObject(1, value); // Query with Integer
value, related record could be queried out
ResultSet resultSet = preparedStatement.executeQuery();
assertTrue(resultSet.next()); // Pass
assertThat(resultSet.getInt(1), is(value)); // Pass
resultSet.close();
}
try (PreparedStatement preparedStatement =
connection.prepareStatement("SELECT * FROM t_order WHERE order_id = ?")) {
preparedStatement.setObject(1, (long) value); // Query with
Long value, related record could NOT be queried out
ResultSet resultSet = preparedStatement.executeQuery();
assertTrue(resultSet.next()); // WRONG
assertThat(resultSet.getInt(1), is(value));
resultSet.close();
}
}
}
```
It was submitted in https://github.com/apache/shardingsphere/pull/37281/files
The similar test code, use raw MySQL JDBC driver, test on MySQL, it works.
### Possible issue 2
If different vendors JRE or different versions of JRE have different
`hashCode()` implementation, then when JRE vendor or version is changed, it'll
cause different routing for the same sharding value.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail:
[email protected]
For queries about this service, please contact Infrastructure at:
[email protected]