Uploaded image for project: 'MariaDB Connector/J'
  1. MariaDB Connector/J
  2. CONJ-698

Statement#getGeneratedKeys() returns two rows if ON DUPLICATE KEY UPDATE statement updated a row

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 2.4.0
    • 2.5.0
    • Other
    • None
    • n/a

    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.

      Attachments

        Issue Links

          Activity

            harawata Iwao AVE! added a comment -

            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 ).

            harawata Iwao AVE! added a comment - 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 ).

            People

              diego dupin Diego Dupin
              harawata Iwao AVE!
              Votes:
              2 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.