Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate-更改现有对象的属性_Java_Hibernate - Fatal编程技术网

Java Hibernate-更改现有对象的属性

Java Hibernate-更改现有对象的属性,java,hibernate,Java,Hibernate,考虑以下情况。我有一个由hibernate保存的对象。对象有一堆对象属性,而这些属性本身就有很多属性。像这样: Mainobject |-Subobject A |--String xyz |-- ... |-Subobject B |-- ... |-Subobject C |- ... 主对象表几乎只引用子对象表 保存和加载对象没有问题,在更改子对象属性(例如xyz)的值时也不会更新。 但是,有时我必须创建所有子对象的新实例,并将这些新子对象指定给现有的主对象。当我保存或更新主对象时,我(

考虑以下情况。我有一个由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);
另一编辑: 没有组合键。每个对象/表都有一个主键。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));
}