Рассмотрите следующую ситуацию. У меня есть объект, который сохраняется в спящем режиме. Объект имеет кучу атрибутов объектов, которые сами имеют массу атрибутов. Вроде так:Hibernate - изменение атрибутов существующего объекта
Mainobject
|-Subobject A
|--String xyz
|-- ...
|-Subobject B
|-- ...
|-Subobject C
|- ...
Основная таблица объектов в значительной степени просто ссылается на таблицы вспомогательных объектов.
Сохранение и загрузка объекта не является проблемой, ни updatig, когда я изменяю значения атрибута подобъекта, например, xyz. Однако мне иногда приходится создавать новые экземпляры всех подобъектов и назначать эти новые подобъекты существующему основному объекту. Когда я сохраняюOrUpdate, основной объект I (очевидно) получает новую строку для каждого из подобъектов, а основной объект обновляется новыми ссылками.
Однако вместо этого я хочу, чтобы Hibernate не создавал новые строки для новых объектов, а просто обновлял старые строки.
Как я могу это достичь? (Я мог бы просто загрузить подобъект и назначить все его новые атрибуты вручную, но их много, и это действительно не очень хороший способ сделать это)
Спасибо!
редактировать: Очень простой пример кода
Mainobject obj = dao.get(MainObject.class, 1L);
obj.setSubobjectA(new SubobjectA());
obj.setSubobjectB(new SubobjectB());
dao.saveOrUpdate(obj);
другой редактировать: Там нет комбинированных ключей. Каждый объект/таблица имеет один ПК. Таблица Mainobject содержит ссылки/внешние ключи для таблиц подобъектов.
редактировать (для пользователя 226 ..): Это как главный объект выглядит:
@Entity
@Table(name="mainobjects")
public class MainObject
{
@Id @GeneratedValue
private Long mainOjectId;
@OneToOne
@JoinColumn(name="ref_subobjectA_id")
@Cascade({CascadeType.SAVE_UPDATE})
private SubobjectA subobjectA;
@OneToOne
@JoinColumn(name="ref_subobjectB_id")
@Cascade({CascadeType.SAVE_UPDATE})
private SubobjectB subobjectB;
// getters/setters
}
Вот как выглядит subobjectA:
@Entity
@Table(name="subobjectsa")
public class SubobjectA
{
@Id
private String subobjectaId;
private String str1;
private String str2;
private String ....
...
// getters/setters
}
SubobjectB выглядит почти так же, ,
В коде Im ищет, существует ли объект:
List<MainObject> existingMainObjects = dao.findByAttributes(MainObject.class, attributeNames, attributeValues);
Если он не я просто не спасти, никаких проблем. Если он существует внутримышечно заменить подобъектов в существующем Mainobject с подобъектов другого mainobject (который разве сохранялись в БД):
if (existingMainObjects.size() == 1)
{
existingMainObjects.get(0).setSubobjectA (someNewMainObject.getSubobjectA);
existingMainObjects.get(0).setSubobjectB (someNewMainObject.getSubobjectB);
dao.saveOrUpdate(existingMainObjects.get(0));
}
Повторим: это не создает новую запись для mainobject, но для подобъектов (потому что его другой объект, чем тот, который сохраняется в Hibernate), он создает новые и обновляет основной объект новыми ссылками. То, что я хочу достичь, - это то, что заменяются только значения в подобъектах.
Мое текущее обходное решение включает использование beanutils для копирования всех свойств, но ключ от нового объекта в существующий объект. Это работает, но, вероятно, очень неэффективно, когда вам нужно сделать это несколько десятых раз.
Edit: Временное решение Хорошо, я думал, используя слияние вместо saveOrUpdate на MainObject должен сделать трюк.Но это не так. Затем я решил попробовать использовать функцию слияния на каждом подобъекте отдельно. По-видимому, это работает по какой-то причине. Может ли кто-нибудь объяснить, почему он не работает, когда я просто объединяю основной объект?
Вы говорите, что вы меняете и обновляете основной объект. Что вы меняете? Первичный ключ основного объекта? И вы используете комбинированные pk? Как отношение базы данных (foregin-key?) Между вашим основным объектом и подобъектом-каскадом? –
Нет, нет, я просто изменяю свои подобъекты. Кроме того, он остается прежним. –
Вы используете foregin-keys? –