我在Spring-Hibernate
应用程序工作。我的问题与orphan removal
有关,如下面的代码所述。
@Entity
public class User {
...........
@OneToMany(mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
List<UserRole> userRoles = new ArrayList<>();
..........
}
考虑save/update User
场景。一种方法是从列表中删除子对象,如user.getUserRoles().remove(userRole)
。
另一种方法可能是将子列表清除为user.getUserRoles().clear()
,然后将其添加到请求中的任何用户角色列表中。在这种情况下,请求中没有出现的用户角色将被orphan removal
删除。
哪一个更好更正确?
嗯,这取决于情况和你正在使用的语义类型;有关不同语义及其性能调优的更多信息,请参阅集合性能。
好吧,在这种情况下,您使用的是一对多关联的列表语义,因此假设您在列表中有20个元素,那么:
选项1:你将一个一个地删除15个元素,并在其中添加1个元素,然后hibernate将发出15个DELETE语句和一个INSERT语句。
选项2:您清除整个列表并手动添加所有6个元素,这样只会发出6条INSERT语句和1条delete语句。
如果列表被大量修改,我将选择选项2,详见一次性删除,如果列表没有被大量修改,我将选择选项1。
除了你的集合和实例的数量,我认为第一种方法(从列表中删除子元素)是最合适的,这正是orphanRemoval
的设计目的。
因为使用orphanRemoval
,您所需要做的就是从关系表中删除子节点,并且该子节点(记录)将自动从原始表中删除。
因为如果你看一下孤儿删除在关系文档你会看到:
当一对一或一对多关系中的目标实体从关系中删除时,通常需要将删除操作级联到目标实体。这样的目标实体被认为是"孤儿",并且可以使用orphanRemoval属性来指定应该删除孤儿实体。
所以我认为最好的方法是让Hibernate自动完成它的工作,而不是手动完成,毕竟这是在Hibernate中使用orphanRemoval
的第一个目的。