Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.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 休眠合并不刷新集合并导致删除_Java_Hibernate - Fatal编程技术网

Java 休眠合并不刷新集合并导致删除

Java 休眠合并不刷新集合并导致删除,java,hibernate,Java,Hibernate,这是我的课 class Teacher { @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true) Set<Students> getStudents() } 班主任{ @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,orphan=true) Set getStudents() } 问题是, 第1课时 步骤1:获取教师

这是我的课

class Teacher {
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true)
Set<Students> getStudents()
}
班主任{
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,orphan=true)
Set getStudents()
}
问题是,

第1课时

步骤1:获取教师id=1,通过在同一会话中调用session.initializeCollection(Teacher.children)初始化学生

步骤2:添加新学生(id=1)

步骤3:合并教师实例以插入添加的学生

第二课时:

步骤1:在会话1的步骤2之前获取教师id=1。使用InitializeCollection(teacher.children)初始化子级

步骤2:执行合并以在会话1中完成任何更改(步骤3之后)

//在这一步中,hibernate id将更新教师并删除学生1

步骤3:添加另一个学生(id=2)并合并教师以保存学生(id=2)

我假设当在步骤2中完成合并2时,它将导致集合使用会话1中所做的更改进行刷新,即将新对象从会话1添加到会话2“子集合”

有人能解释为什么会发生这种情况,以及应该如何处理对象,以便在会话2中,通过对表的任何更改(即将任何子对象添加到表中)刷新students集合吗

另外,请注意,在步骤1之后,教师对象是一个分离的实例,因为该对象被传递到基于web的视图层,并在步骤2中进行修改,在步骤3中重新附加


getStudents是懒惰的,因此集合永远不会在会话2中实现。当您调用merge时,它会看到一个空集合,并假定这是您想要的,因此它会从持久对象中删除学生。在课时2中,您应该确保在合并或添加新学生之前调用getStudents。

我更新了步骤,在步骤1中初始化了children集合,因此我假设惰性集合不会有问题。在课时2中,您仍然有没有在课时1中添加的学生的集合,这就是为什么在会话2中合并时会删除它。您没有正确考虑“合并”。您可以说
步骤2:执行合并以在会话1中完成任何更改(步骤3之后)
,但合并并不是这样做的。再次阅读我粘贴的文档。根据行为,我猜您没有实体的版本列?那可能会帮你缓解这个问题。好吧,看来我完全误解了。那么,在这种情况下,可以同时更新子集合的正确模式是什么呢。我想最好的方法是直接插入子级,而不是在父级上使用级联操作进行合并,或者在添加子级之前完全重新蚀刻父级(如果使用合并)?要求可以同时添加子项。我尝试在父级和子级上使用版本列,但结果相同。最好的方法是使用版本列。Hibernate或JPA将使用该列。然后,当您尝试写入对象时,如果您当前的版本与数据库中的版本不同,您将得到一个异常,然后您将知道您已过期,此时您将从数据库刷新对象,再次应用更改,然后再次尝试保存。如果我使用版本列,是在父母身上还是在孩子身上。如果我在父对象上使用它,即使我没有对父对象字段进行任何更改,只是在子集合中添加/删除,它也会被更新吗?