Будьте в спящем режиме: Оборотная сторона слияния () по обновлению ()

У меня есть проблемы с a NonUniqueObjectException брошенный В спящем режиме.

Читая документы и это сообщение в блоге, я заменил вызов от update() к merge(), и это решило проблему.

Я полагаю, что понимаю причину исключения, и почему изменение метода решило проблему, с точки зрения разъединенных объектов и границ сессии.

Мой вопрос: учитывая, что merge() будет всегда решать к объекту сессии или получать его, если это не будет существовать, называет слияние () обычно более безопасной альтернативой, чем update()?

Какова оборотная сторона использования merge() update()?

29
задан Marty Pitt 22 January 2010 в 15:25
поделиться

2 ответа

Это практически определенно потому, что ваш экземпляр MySQL не работает, либо вы не настроили конфигурацию / database.yml, чтобы быть указанным в правой базе данных для вашей среды (обычно развитие). Вот пара вещей, чтобы попробовать -

  • Проверьте свой Config / database.yml - Где ваш хост (если нет хоста Перечислены, это подключится к localhost)
  • Попробуйте запустить mysql -h localhost и Посмотрите, работает ли MySQL.

Редактировать: Если вы не можете подключиться к базе местных баз данных, то проблема в том, что не с рельсами. Убедитесь, что у вас он работает, и что ваши разрешения устанавливаются правильно, чтобы разрешить подключение с вашей машины. Кроме того, попробуйте подключиться к корню с локальной машины, чтобы увидеть, является ли это более гранулированная проблема (например, у вас есть локальные подключения, но не для пользователя, которые вы используете в Rails).

Редактировать 2: В этом случае ваша проблема, вероятно, состоит в том, что ваша база данных не была создана. Просто перейдите в командную строку и введите следующее:

root mysql -u root-p -e 'Создать базу данных Railslist_development;'

Это должно создать базу данных и позволить вам запускать свою миграцию.

-121--4349572-

- это призывая слияние (), как правило, более безопасная альтернатива, чем обновление ()?

как способ избежать неисполнения, да. Я думаю, что это объясняет, почему JPA не допускает метод обновления.

Какой недостаток использует объединение () над обновлением ()?

Непрошедший пользователь может подумать, что он или она имеет новую управляемую сущность. Что-то вроде

// myEntity (passed as parameter does not become managed)
// Only the one returned by the merge operation is a managed entity
session.merge(myEntity);

// "newValue" is not commited because myEntity is not managed
myEntity.setMyProperty("newValue");

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

  • Добавить столбец версии (@version). 0 или NULL версия Указывает, что экземпляр новый и должен быть вставлен, не обновляется
  • Использовать перехватчик Hibernate
  • Если вы уверены, что хотите обновить вместо вставки, вы можете использовать Следующий подход

...

public void updateMyEntity(MyEntity updateableMyEntity);

    // load does not hit the database
    MyEntity myEntity = (MyEntity) session.load(MyEntity.class, updateableMyEntity.getId());

    BeanUtils.copyProperties(myEntity, updateableMyEntity);

}

Таким образом, вы можете обновить свою сущность без слияния или обновления метода. Смотрите этот вопрос для получения дополнительной информации: Лучший способ обновить некоторые поля отдельного объекта на Hibernate?

41
ответ дан 28 November 2019 в 01:43
поделиться

Используйте update(), если вы уверены, что сессия не содержит уже постоянный экземпляр с тем же самым идентификатором, и merge(), если вы хотите объединить ваши модификации в любое время без учета состояния сессии. Другими словами, функция update() обычно является первым методом, который Вы вызываете в свежем сеансе, гарантируя, что повторное присоединение Ваших отсоединенных экземпляров будет первой выполненной операцией.

4
ответ дан 28 November 2019 в 01:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: