2015-02-18 14 views
0

В Hibernate вы можете использовать @SQLInsert для определения пользовательского запроса на вставку. Hibernate используют подготовленные заявления, поэтому вам просто нужно обеспечить ? в качестве заполнителя, например: INSERT INTO table (colA, colB) VALUES (?,?)Hibernate @SQLInsert и On Duplicate Key

На дубликате ключа для colA, я хочу colB быть обновлен с новым значением, поэтому я попытался INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY UPDATE colB = ? - Это, однако, выдает ошибку, указанную третьим параметром. (Не указано значение для параметра 3)

Каков правильный способ написать этот запрос для спящего режима? Любое обновление, не зависящее от данных, например INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY UPDATE colB = colB +1, работает, но мне нужно установить фактическое значение colB, которое было передано с помощью вставки.

ответ

0

Правильный ответ должен были бы использовать следующее заявление:

INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY 
UPDATE colB = VALUES(colB); 

Однако тогда проблема появляется, что спящий режим не получит значение автоматического приращения назад, когда был выполнен оператор обновления.

Я нашел пост следующего блог (http://www.jroller.com/mmatthews/entry/getting_hibernate_and_mysql_s) и доработанный запрос на следующее:

INSERT INTO table (colA, colB) VALUES (?,?) ON DUPLICATE KEY 
UPDATE colB = VALUES(colB), id = LAST_INSERT_ID(id); 

, который, наконец, работает.

Неразрешимая проблема с этим подходом заключается в том, что вставка двух объектов, которые равны внутри одной и той же транзакции, не работает. Даже если вторая вставка приведет к правильному обновлению, em закончит с двумя сущностями-экземплярами, представляющими одну и ту же строку базы данных, что запрещено.

Чтобы решить эту проблему, нужно просто убедиться, что вы не вставляете 2 объекта, которые оказываются равными из-за их ограничений. (Я использовал ту же логику для equals/hashcode как ограничение составного уникального ключа, поэтому я могу устранить такие дубликаты при выполнении пакетных вставок)