Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Hibernate SpringDataJPA:保存在一个事务中在父级之间移动子级的父级列表_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Hibernate SpringDataJPA:保存在一个事务中在父级之间移动子级的父级列表

Hibernate SpringDataJPA:保存在一个事务中在父级之间移动子级的父级列表,hibernate,jpa,spring-data-jpa,Hibernate,Jpa,Spring Data Jpa,我有一个家长列表,其中每个一对多家长都有一个多对一孩子的列表。孤立项删除处于启用状态,并且关系处于延迟状态 我在Hibernate中使用了一个JpaRepository 我需要在父级之间移动子级,并在单个事务中保存所有更改 如果我加载父母列表,在他们之间移动孩子(通过更新关系的双方),并在循环中逐个保存列表中的人,这样每个人都可以保存在自己的事务中,那么效果会很好 但是,当我将循环放入一个带有@Transactional注释的方法中,以便将整个保存过程保存在一个全局事务中并回滚时,如果其中一个保

我有一个家长列表,其中每个一对多家长都有一个多对一孩子的列表。孤立项删除处于启用状态,并且关系处于延迟状态

我在Hibernate中使用了一个
JpaRepository

我需要在父级之间移动子级,并在单个事务中保存所有更改

如果我加载父母列表,在他们之间移动孩子(通过更新关系的双方),并在循环中逐个保存列表中的人,这样每个人都可以保存在自己的事务中,那么效果会很好

但是,当我将循环放入一个带有
@Transactional
注释的方法中,以便将整个保存过程保存在一个全局事务中并回滚时,如果其中一个保存调用失败,子项有时将无法正确存储

当我在单独的事务中逐个保存时,如果子行已从另一个父行移动到当前正在保存的父行,Hibernate只会更新该子行;如果子行已从当前正在保存的父行中删除,则会删除并重新插入该子行。我可以在SQL日志中看到这一点

当我在一个事务中保存时,这似乎失败了:一些子项没有正确移动,而是丢失了

我还尝试使用
saveAll()
代替
@Transactional
方法中的循环,效果相同


在父实体之间移动子实体并在单个事务中保存所有父实体是否不受支持?

严格来说,这不是您想要的,但一个选项可能是不重用子实体,而是分配它们的副本

在每个源父级上,您将删除要移动的子级,然后将其副本添加到目标实体

然后,您应该能够在以这种方式更改的父实体列表上调用
crudepository#saveAll()
,并获得预期结果


需要注意的是,移动的子项上的ID将在数据库中更改,因为它们将被删除,然后重新插入。解决方案在性能方面不是最优的,因为您将在DB和Java级别上做更多的工作。

这似乎失败了
错误是什么?我认为问题是,当你在父母之间交换孩子时,在大交易中会发生一些冲突。我不能100%确定您是否有一个事务,是否有循环的方法,是否也用
@transaction
注释?否则,您将不会有一个单一的事务FYII已更新的问题:失败的是,一些孩子迷路了。我有一个junit测试,它在服务bean上调用一个方法,该方法使用
crudepository.save(列出父项)
保存在一个循环中,并用@Transactional注释。当您更改父项时,是否同时更新
child.setParent()
parent.setChild()
?您的问题非常广泛,您是否可以尝试测试案例&尝试找到一个存在问题的小示例?比如当父母A和父母B交换孩子时,父母B没有孩子,就像这样?是的,这就是我所说的“我更新关系的双方”。我将尝试提取一个干净的测试用例。感谢您的快速响应。这解决了任务,但可能会导致相当多的数据库流量,因为需要删除和重新插入子项及其子项。如果没有更好的解决方案,我会接受答案。另一个警告:hibernate在删除原始子项之前将子项作为重复项插入,即子项不能具有需要在相应表中唯一的域属性。