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]

Reply via email to