Hibernate Обновление существующего объекта новым объектом
Предположим, у меня есть сущность Foo в БД.
Я анализирую некоторые файлы и создаю новые объекты Foo и хотел бы проверить, существует ли проанализированный объект Foo в БД (используя уникальный атрибут). Если он уже существует, обновите его, в противном случае сохраните как новый объект.
Каков наилучший подход?
Могу ли я просто установить идентификатор и версию в новом объекте Foo?
Или мне лучше загрузить объект Foo из БД и скопировать свойства из проанализированного файла?
Благодарю.
3 ответа
Скажем, у Foo есть некоторые свойства размера, цвета и выравнивания.
Таким образом, Foo в базе данных имеет эти свойства (и вы уже определили, что это правильное значение с использованием вашего атрибута уникальности)
id=1, size=12, color=null, alignment="c"
Тогда скажем, что новый объект Foo (new Foo) имеет следующие свойства
id=(none yet), size=14, color="red", alignment=null
У вас есть варианты: либо использовать метод saveOrUpdate(), либо метод merge(). И то и другое приведет к тому, что новый объект будет сохранен поверх старого объекта, но с сохранением идентификатора старого объекта. Сохраненный новый объект будет иметь свойства new Foo выше, но с идентификатором, установленным в 1.
Однако, если вы хотите переопределить только определенные свойства Foo, вам, возможно, придется загрузить объект из базы данных и скопировать их вручную. Например, в этом случае выравнивание перезаписывается нулем. Если вы хотите, чтобы выравнивание было перезаписано только в тех случаях, когда новое значение не равно нулю, то я думаю, что вам нужно скопировать значения вручную.
Если вы не уверены, что объект находится в базе данных, то это, вероятно, отдельный объект. Вы можете сделать так, чтобы hibernate выбирал, сохранять или обновлять объект, устанавливая идентификатор и все другие поля и вызывая "saveOrUpdate". Все это есть в документации - раздел 10.7
Если у вас нет идентификатора в файле, который вы анализируете, ваш объект настолько сложен, что использовать hql для его обновления не вариант?
лайк:
getHibernateTemplate().bulkUpdate("Update Foo set p1 = ?, ... where uniq_prop = ?", new Object[] {..., key});
Если вы сначала загрузите объект, вы выдадите команду select by update, которая удвоит количество запросов, которые вы отправите в базу данных. Опция обновления hql также имеет то преимущество, что вы не загружаете сеанс гибернации многими объектами (а при анализе большого файла размер сеанса может стать чем-то, что нужно отслеживать).