Java Hibernate-更改现有对象的属性
考虑以下情况。我有一个由hibernate保存的对象。对象有一堆对象属性,而这些属性本身就有很多属性。像这样:Java Hibernate-更改现有对象的属性,java,hibernate,Java,Hibernate,考虑以下情况。我有一个由hibernate保存的对象。对象有一堆对象属性,而这些属性本身就有很多属性。像这样: Mainobject |-Subobject A |--String xyz |-- ... |-Subobject B |-- ... |-Subobject C |- ... 主对象表几乎只引用子对象表 保存和加载对象没有问题,在更改子对象属性(例如xyz)的值时也不会更新。 但是,有时我必须创建所有子对象的新实例,并将这些新子对象指定给现有的主对象。当我保存或更新主对象时,我(
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);
另一编辑:
没有组合键。每个对象/表都有一个主键。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
}
子对象的外观如下所示:
@Entity
@Table(name="subobjectsa")
public class SubobjectA
{
@Id
private String subobjectaId;
private String str1;
private String str2;
private String ....
...
// getters/setters
}
子对象B看起来几乎相同
在代码中,我查看对象是否存在:
List<MainObject> existingMainObjects = dao.findByAttributes(MainObject.class, attributeNames, attributeValues);
重申:这不会为mainobject创建新条目,但会为子对象(因为它与Hibernate持久化的对象不同)创建新条目,并使用新引用更新主对象。我想要实现的基本目标是,只替换子对象中的值
我目前的解决方法包括使用beanutils将所有属性(除了键)从新对象复制到现有对象中。这是可行的,但是当你不得不做几十次的时候,效率可能会很低
编辑:临时解决方案
好的,我在想在main对象上使用merge而不是saveOrUpdate应该可以做到这一点。但事实并非如此。然后我决定在每个子对象上单独使用merge函数。这似乎出于某种原因起作用。有人能解释为什么我合并主对象时它不起作用吗?您正在将两个新对象设置为MainObject。 现在,当您将新对象设置为外键时,因为您说过mainObjectC引用子对象A和子对象B,所以Hibernate将在主表(即子对象A和子对象B)中搜索这些对象。如果它找到了任何匹配项,那么它会很好,否则它会在那里创建新的enrties(子对象A和子对象B分别),并插入主项目 您可以做的是,只将那些已经存在于子对象A和子对象B中的对象(子对象A和子对象B)放在MainObject中。
对于新条目,首先插入子对象A和子对象B,然后插入主对象。您说您更改并更新了主对象。你要换什么?主对象的主键?你使用组合pk吗?主对象和子对象更新级联之间的数据库关系(foregin键?)如何?不,不,我只是更改它的子对象。除此之外,它保持不变。你用外国钥匙吗?我不确定我是否理解这个问题。我确实用外键。你的意思是我是否在我的类中声明外键?答案是肯定的,我使用@JoinColumn注释来声明主类和子类之间的关系?具体来说,如何映射子对象中的标识符?
if (existingMainObjects.size() == 1)
{
existingMainObjects.get(0).setSubobjectA (someNewMainObject.getSubobjectA);
existingMainObjects.get(0).setSubobjectB (someNewMainObject.getSubobjectB);
dao.saveOrUpdate(existingMainObjects.get(0));
}