2017-02-10 2 views
1

バッチ挿入中に生成されたキーを取得中にエラーが発生しました。 バッチ挿入が正常に機能します。MyBatis useバケットインサート内のネストされたオブジェクトのキー

オブジェクト構造:

オブジェクト1:

Long id, String name, Obj2 obj 

対象2:(OBJ2)

Long id, String value 

オブジェクトの両方が異なるテーブルに格納されています。

オブジェクト1

id | name | object2_id (Foreign Key) 

object2は

id | value 

今私は挿入するオブジェクト1のリストを持っています。

プロセスは、インサート対象2ことIDを取得し、(外部キーなど)Object2にの "ID" とオブジェクト1を挿入します。

Object2に、Mapper.xml

に入れ子

ケースを挿入しながら1:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1s.obj2.id"> 
<!-- obj1s is name of the list --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object.

ケース2:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1.obj2.id"> 
<!-- obj1 so as to access the object of foreach loop --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj1' not found. Available parameters are [obj1s, param1]

ケース3:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id"> 
<!-- obj2 is the object with variable id to store generated key --> 
    insert into object2 (value) values 
     <foreach collection="obj1s" item="obj1" separator=","> 
      (#{obj1.obj2.id}) 
     </foreach> 
</insert> 

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj2' not found. Available parameters are [obj1s, param1]

これを達成するためにとにかくはありますか? selectKeyを使用している可能性がありますが、自動生成されたキーをサポートしていないDBでは、selectkeyが使用されます。

MyBatis 3.3.1およびMysqlの使用。

+0

マッピングクラス/プロパティを明確にしてください<=>テーブル/カラム – blackwizard

+0

@blackwizardマッピングは列名とプロパティ名で分かります。 – Shuddh

答えて

6

私はそれを理解しました。 MyBatisには、複数行のinsertとuseGeneratedキーのバグがあります。バグはリストの変数名ですはバッチ挿入と生成されたキーを取得するときに "リスト"でなければなりません。それに応じてオブジェクトにアクセスします。だから、上記のコードemxampleのために次のようになります。

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id"> 
<!-- obj2 is the object with variable id to store generated key --> 
insert into object2 (value) values 
    <foreach collection="list" item="obj1" separator=","> 
     (#{obj1.obj2.id}) 
    </foreach> 

とmapper.javaメソッドの宣言は次のようになります。

public Integer batchInsert(@Param("list")List<Obj1> obj1); 

変数の名前がリストでなければなりません。他に何もない。

@blackwizardさん、ありがとうございました。私はこの回答に私を上陸させたバグを再確認してチェックしなければなりません。

+0

あなたはそのバグへのリンクがありますか? –

+0

彼らはこのように設計したようです。私はそのリンクを検索しなければならないかもしれない。 1年前に開発者と話し合った。 – Shuddh

0

あなたはOBJ2は型名で、obj.idは、OBJは、プロパティ名でアクセスする必要があります。

さらに、生成されたキーを検索することは、個々の挿入物に対してのみ機能する/意味を成します。 確かに:N個のレコードを挿入したいのですが、あなたのコードは単一の(巨大な)ステートメントを生成して実行します。これはバッチではありません。

Javaであなたのリストを繰り返し、ループ内でより簡単なinsert文(それ以上のforeachはありません)を呼び出すと、生成されたすべてのキーを一致するオブジェクトにバインドできます。 ExecutorType.REUSEを指定してSqlSessionを開き、ステートメントが1回だけ準備されるようにします。各繰り返しでパラメータが送信されます。

私はすでにthis kind of questionに回答しています。

+0

私はプロパティ名のみでアクセスしています。そして、私は単一の(巨大な)ステートメントを使用すると、すべての行に対して生成されたキーを取得できますが、リストのネストされたオブジェクトは取得できません。 – Shuddh

+0

あなたが正しいです、私はドキュメントを見直しました。複数行の挿入を使用する場合、自動生成キーを取得することは本当に可能です。 – blackwizard

+0

あなたのmybatisスニペットによれば、_obj2_という名前のプロパティにアクセスし、プロパティ名はクラス定義の_obj_です:Obj2 obj、少なくともBindingExceptionを説明するタイプミスです。 – blackwizard

関連する問題