7

トランザクションから生成されたキーを取得しようとしていますexecuteBatch()が、最後に追加されたキーしか取得できません。

これは私のコードです:

        PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);          
        for (int i = 0 ; i < adding_dates.length ; i++){
            ps_insert.setInt(1, Integer.parseInt(consultant_id));
            ps_insert.setDate(2, adding_dates[i]);
            ps_insert.setInt(3, Integer.parseInt(room_id));
            ps_insert.addBatch();
        }
        ps_insert.executeBatch();
        ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved
        conn.commit();          

私は何が間違っているのですか?

編集:埋め込みモードでH2(http://www.h2database.com/html/main.html)データベースを使用していることに言及しなかったことをお詫びします。

4

4 に答える 4

3

H2 jdbcドライバーjavadocsによると、これは通常の動作です。

この接続に対して最後に生成された自動インクリメント キー(存在する場合)を含む結果セットを返します。最後の変更ステートメントによってキーが生成されなかった場合は、空の結果セットが返されます。返される結果セットには、最後の行のデータのみが含まれます。

于 2013-01-29T10:51:51.537 に答える
1

ResultSetキーを取得するには、を繰り返す必要があります。

  PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);          
    for (int i = 0 ; i < adding_dates.length ; i++){
        ps_insert.setInt(1, Integer.parseInt(consultant_id));
        ps_insert.setDate(2, adding_dates[i]);
        ps_insert.setInt(3, Integer.parseInt(room_id));
        ps_insert.addBatch();
    }
    ps_insert.executeBatch();
    ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved

    if (rs.next()) {
       ResultSetMetaData rsmd = rs.getMetaData();
       int colCount = rsmd.getColumnCount();

       do {
           for (int i = 1; i <= colCount; i++) {
             String key = rs.getString(i);
             System.out.println("key " + i + "is " + key);
           }
       }
      while (rs.next();)
     } 

    conn.commit();        
于 2013-01-29T10:45:43.380 に答える
1

これはH2実装の制限です。これは問題です。

今のところ、バッチなしで挿入/更新を使用するか、selectを介して生成されたキーをクエリします。

于 2013-01-29T10:59:06.000 に答える
0

2つのスレッド間でセッション/接続を共有していて、それらのスレッドの2つが同時にステートメントを実行しようとすると、この種の問題が発生する可能性があります。

おそらく、(a)接続プールを使用するか、(b)DBへのアクセス全体を同期する必要があります。

たとえば、オプション(b)の場合

synchronizeメソッドの前にトークンを配置して、スレッドセーフにします

私はあなたが完全な実行コンテキストを知らないのでちょうど考え

于 2013-01-29T10:46:15.133 に答える