Спящий режим + логика «ON DUPLICATE KEY» - PullRequest
6 голосов
/ 10 марта 2011

Я ищу способ сохранять или обновлять записи в соответствии с уникальным ключом таблицы, состоящим из нескольких столбцов).

Я хочу добиться той же функциональности, что и INSERT ... ON DUPLICATE KEY UPDATE, то есть слепо сохранить запись и заставить DB / Hibernate вставить новую или обновить существующую, если уникальный ключ уже существует.

Я знаю, что могу использовать @SQLInsert( sql="INSERT INTO .. ON DUPLICATE KEY UPDATE"), но я надеялся не писать свои собственные SQL и позволить Hibernate делать эту работу.(Я предполагаю, что это будет работать лучше - иначе зачем использовать Hibernate?)

Ответы [ 3 ]

3 голосов
/ 13 января 2015

Hibernate может выдать ConstraintViolationException при попытке вставить строку, которая нарушает ограничение (включая ограничение уникальности). Если вы не получите это исключение, вы можете получить другое общее исключение Hibernate - это зависит от версии Hibernate и способности Hibernate сопоставить исключение MySQL с исключением Hibernate в версии и типе базы данных, которую вы используете ( Я не проверял это на всем).

Исключение вы получите только после вызова flush(), поэтому убедитесь, что оно также есть в вашем блоке try-catch.

Я бы позаботился о реализации решений, в которых вы проверяете, что строка существует первой. Если несколько сеансов обновляют таблицу одновременно, вы можете получить условие гонки. Два процесса читают строку в одно и то же время, чтобы узнать, существует ли она; они оба обнаруживают, что его там нет, и затем они оба пытаются создать новую строку. Один из них провалится в зависимости от того, кто выиграет гонку.

Лучшее решение состоит в том, чтобы сначала попытаться вставить и, если это не удастся, предположить, что она уже была там. Однако, как только у вас возникнет исключение, вам придется откатиться, что ограничит возможности использования этого подхода.

1 голос
/ 10 марта 2011

Это не похоже на чистый подход ко мне. Было бы лучше сначала посмотреть, существует ли сущность с данным ключом (ключами). Если это так, обновите его и сохраните, если не создайте новый.

EDIT

Или, возможно, подумайте, если вы ищете merge ():

  • если существует постоянный экземпляр с тем же идентификатором, который в настоящее время связан с сеансом, скопируйте состояние данного объекта в постоянный экземпляр
  • если в данный момент нет постоянного экземпляра, связанного с сеансом, попробуйте загрузить его из базы данных или создать новый постоянный экземпляр
  • постоянный экземпляр возвращается
  • данный экземпляр не становится связанным с сеансом, он остается отсоединенным

<<a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html" rel="nofollow">http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html

0 голосов
/ 10 марта 2011

Вы можете использовать saveOrUpdate () из класса Session.

...