2017-02-10 12 views
1

В то время как пакетная вставка и получение сгенерированного ключа, получение ошибки. Пакетная вставка работает нормально.MyBatis useGeneratedKeys для вложенного объекта в пакетной вставке

Структура объекта:

Объект 1:

Long id, String name, Obj2 obj 

Объект 2: (obj2)

Long id, String value 

Оба эти объекты хранятся в различных таблицах.

Таблица object1

id | name | object2_id (Foreign Key) 

Таблица object2

id | value 

Теперь у меня есть список объекта 1 для вставки.

Этот процесс будет вставка объекта 2 получить идентификатор и вставьте объекта 1 с "ID" из Объект2 (как внешний ключ).

При вставке Объект2, блок вставки в 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, но selectkey используется для DB, не поддерживающих Autogenerated key.

Использование MyBatis 3.3.1 и Mysql.

+0

уточните класс/свойства отображения <=> таблица/столбцы – blackwizard

+0

@blackwizard Отображение может быть определено столбцами и именами свойств. – Shuddh

ответ

6

Итак, я понял. Существует эта ошибка с MyBatis для многострочной вставки и использования генерируемого ключа. Ошибка - это имя переменной списка должно быть «списком» при вставке пакета и получении сгенерированного ключа. Затем соответствующим образом получите доступ к объекту. Так выше 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

Кажется, они спроектировали его таким образом. Возможно, мне придется искать ссылку. Обсуждался с разработчиками год назад. – Shuddh

0

Вы должны получить доступ к obj.id, OBJ это имя свойства, obj2 это имя типа.

Кроме того, получение сгенерированного ключа работает/имеет смысл только для отдельных вставок. Действительно: вы хотите вставить N записей, но ваш код будет генерировать и выполнять один (гигантский) оператор. Это не пакет.

Итерации над вашим списком в Java, вызовите более простой оператор insert (не более foreach там) в цикле, тогда каждый сгенерированный ключ может быть привязан к соответствующему объекту. Откройте SqlSession с ExecutorType.REUSE, чтобы оператор был подготовлен только один раз, на каждой итерации отправляются только параметры.

Я уже ответил this kind of question.

+0

Я получаю доступ только через имя свойства. И когда я использую одиночный (гигантский) оператор, я могу получить сгенерированные ключи для всех строк, но не для вложенных объектов для списка. – Shuddh

+0

Вы правы, я только что просмотрел документ, извлечение автоматически сгенерированных ключей действительно возможно при использовании многострочных вставок. – blackwizard

+0

Я имел в виду, что в соответствии с вашими описаниями mybatis вы получаете доступ к свойству с именем _obj2_, а имя свойства - _obj_ в определении класса: «Obj2 obj» - просто опечатка, которая объясняет, по крайней мере, исключение BindingException. – blackwizard