考虑以下情况。我有一个由休眠保持的对象。该对象具有一堆对象属性,这些属性本身具有大量属性。像这样:
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。主对象表保存子对象表的引用/外键。
编辑(对于用户 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 中的子对象替换为另一个 mainobject 的子对象(未保留在 db 中):
if (existingMainObjects.size() == 1)
{
existingMainObjects.get(0).setSubobjectA (someNewMainObject.getSubobjectA);
existingMainObjects.get(0).setSubobjectB (someNewMainObject.getSubobjectB);
dao.saveOrUpdate(existingMainObjects.get(0));
}
重申一下:这不会为主对象创建新条目,但对于子对象(因为它与 Hibernate 持久化的对象不同)它会创建新对象并使用新引用更新主对象。我基本上想要实现的是只替换子对象中的值。
我当前的解决方法包括使用 beanutils 将除键之外的所有属性从新对象复制到现有对象中。这很有效,但是当你必须这样做几万次时可能效率很低。
编辑:临时解决方案 好的,我想在 MainObject 上使用 merge 而不是 saveOrUpdate 应该可以解决问题。但它没有。然后我决定尝试在每个子对象上单独使用合并功能。这似乎出于某种原因。谁能解释为什么我只合并主要对象时它不起作用?