2013-07-18 2 views
0

Рассмотрите следующую ситуацию. У меня есть объект, который сохраняется в спящем режиме. Объект имеет кучу атрибутов объектов, которые сами имеют массу атрибутов. Вроде так: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 должен сделать трюк.Но это не так. Затем я решил попробовать использовать функцию слияния на каждом подобъекте отдельно. По-видимому, это работает по какой-то причине. Может ли кто-нибудь объяснить, почему он не работает, когда я просто объединяю основной объект?

+0

Вы говорите, что вы меняете и обновляете основной объект. Что вы меняете? Первичный ключ основного объекта? И вы используете комбинированные pk? Как отношение базы данных (foregin-key?) Между вашим основным объектом и подобъектом-каскадом? –

+0

Нет, нет, я просто изменяю свои подобъекты. Кроме того, он остается прежним. –

+0

Вы используете foregin-keys? –

ответ

1

Вы устанавливаете два новых объекта в объект MainObject. Теперь, когда вы устанавливаете новые объекты на внешний ключ, так как вы сказали, что ваши ссылки MainObjecct SubobjectA и SubobjectB, Hibernate будет искать эти объекты в главной таблице i.e SubobjectA и SubobjectB. Если он найдет какое-либо совпадение, то его штраф, другой мудрый он создаст новые enrties там (SubobjectA и SubobjectB отдельно) и вставьте свой MainOject.

Что вы можете сделать, это положить только те объекты (SubobjectA и SubobjectB) в MainObject, которые уже присутствуют в SubobjectA и SubobjectB. Для новых записей сначала вставьте в SubobjectA и SubobjectB, затем в MainObject.

Смежные вопросы