[CONJ-698] Statement#getGeneratedKeys() returns two rows if ON DUPLICATE KEY UPDATE statement updated a row Created: 2019-04-17  Updated: 2019-10-02  Resolved: 2019-10-01

Status: Closed
Project: MariaDB Connector/J
Component/s: Other
Affects Version/s: 2.4.0
Fix Version/s: 2.5.0

Type: Bug Priority: Major
Reporter: Iwao AVE! Assignee: Diego Dupin
Resolution: Fixed Votes: 2
Labels: None
Environment:

n/a


Issue Links:
Relates
relates to CONJ-706 getGeneratedKey implementation correc... Closed

 Description   

When INSERT ... ON DUPLICATE KEY UPDATE statement updated a row, the ResultSet returned from getGeneratedKeys() contains two rows.
Here is a failing test case (I wrote it in MultiTest).

  @Test
  public void shouldDuplicateKeyUpdateNotReturnExtraRows() throws Throwable {
    try (Connection con = openNewConnection(connUri, new Properties())) {
      try (Statement stmt = con.createStatement()) {
        stmt.execute("truncate table testMultiGeneratedKey");
      }
      try (PreparedStatement pstmt = con.prepareStatement(
          "INSERT INTO testMultiGeneratedKey (id, text) VALUES (?, ?) "
              + "ON DUPLICATE KEY UPDATE text = VALUES(text)",
          Statement.RETURN_GENERATED_KEYS)) {
        // Insert a row.
        pstmt.setInt(1, 1);
        pstmt.setString(2, "initial");
        assertEquals(1, pstmt.executeUpdate());
        try (ResultSet rs = pstmt.getGeneratedKeys()) {
          assertTrue(rs.next());
          assertEquals(1, rs.getInt(1));
          assertFalse(rs.next());
        }
        // Update the row.
        pstmt.setInt(1, 1);
        pstmt.setString(2, "updated");
        assertEquals(2, pstmt.executeUpdate());
        try (ResultSet rs = pstmt.getGeneratedKeys()) {
          assertTrue(rs.next());
          assertEquals(1, rs.getInt(1));
          assertFalse(rs.next());
        }
      }
    }
  }

getGeneratedKeys() ultimately calls org.mariadb.jdbc.internal.com.read.dao.CmdInformationSingle.getGeneratedKeys(Protocol).
In this method, updateCount is used as the size of returned result set, however, updateCount is 2 when INSERT ... ON DUPLICATE KEY UPDATE statement updated a row according to the doc.



 Comments   
Comment by Iwao AVE! [ 2019-05-23 ]

I checked MySQL Connector/J implementation and it returns one row when the statement contains DUPLICATE KEY UPDATE.
Although it is not ideal, that might be the least problematic solution because it seems to be difficult to get the actual number of generated keys and the extra row makes it difficult for SQL mapper tools like MyBatis to assign generated keys (e.g. https://github.com/mybatis/mybatis-3/issues/1523 ).

Generated at Thu Feb 08 03:17:39 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.