考虑以下情况。我有一个由hibernate持久化的对象。该对象具有一堆对象属性,这些属性本身具有大量属性。像这样:
Mainobject
|-Subobject A
|--String xyz
|-- ...
|-Subobject B
|-- ...
|-Subobject C
|- ...
主对象表几乎只引用子对象表。
保存和加载对象没有问题,当我更改子对象属性的值时也不会更新,例如xyz。 但是,我有时必须创建所有子对象的新实例,并将这些新子对象分配给现有主对象。当我保存或更新主对象时(显然)为每个子对象获取一个新行,并使用新引用更新主对象。
然而,我想要实现的是,Hibernate不会为新对象创建新行,而只是更新旧行。
我怎样才能做到这一点? (我可以加载子对象并手动分配它的所有新属性,但是它们有很多,并且这看起来不是一个好方法)
谢谢!
编辑:非常基本的示例代码
Mainobject obj = dao.get(MainObject.class, 1L);
obj.setSubobjectA(new SubobjectA());
obj.setSubobjectB(new SubobjectB());
dao.saveOrUpdate(obj);
另一个编辑: 没有组合键。每个对象/表都有一个PK。 Mainobject Table保存子对象表的引用/外键。
编辑(对于用户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看起来几乎一样。
在代码中我查看对象是否存在:
List<MainObject> existingMainObjects = dao.findByAttributes(MainObject.class, attributeNames, attributeValues);
如果不是我只是保存,没问题。如果确实存在,则将现有Mainobject中的子对象替换为另一个主对象的子对象(不存在于db中):
if (existingMainObjects.size() == 1)
{
existingMainObjects.get(0).setSubobjectA (someNewMainObject.getSubobjectA);
existingMainObjects.get(0).setSubobjectB (someNewMainObject.getSubobjectB);
dao.saveOrUpdate(existingMainObjects.get(0));
}
重申:这不会为main对象创建新条目,但对于子对象(因为它与Hibernate持久化的对象不同),它会创建新对象并使用新引用更新主对象。我想要实现的目标是只替换子对象中的值。
我目前的解决方法包括使用beanutils将所有属性复制到现有对象中,但将密钥从新对象复制到现有对象中。这种方法很有效,但是当你不得不这样做几万次时效率非常低。
编辑:临时解决方案 好吧我想在MainObject上使用merge而不是saveOrUpdate应该可以解决问题。但它没有。然后我决定尝试在每个子对象上单独使用合并功能。这似乎是出于某种原因。任何人都可以解释为什么当我刚刚合并主要对象时它不起作用?
答案 0 :(得分:1)
您正在为MainObject设置两个新对象。 现在,当您在外键上设置新对象时,由于您说您的MainObjecct引用了SubobjectA和SubobjectB,Hibernate将在主表中搜索这些对象,即SubobjectA和SubobjectB。如果它找到任何匹配然后它的罚款,另外它将在那里创建新的enrties(分别为SubobjectA和SubobjectB)并插入你的MainOject。
您可以做的是,只将那些对象(SubobjectA和SubobjectB)放在MainObject中已经存在于SubobjectA和SubobjectB中的对象中。 对于新条目,首先在SubobjectA和SubobjectB中插入然后在MainObject中插入。