大家讨论下如何使用Hibernate实现逻辑删除吧

如果项目里有大量的数据想使用逻辑删除,就是假删除,我们会在数据库的表里放一个ds字段来区分是否删除。
设想删除数据时,我们统一用的dao的delete方法来删除,而delete方法中则使用setDs(true)来做逻辑删除。
但是,这样一来两个问题出现了:
1. 逻辑删除一个实体时,需要级联删除的子表对象如何才能自动一起逻辑删除掉。
2. 当子表的几行被逻辑删除掉了,用主表对象类似myeo.getxxxlist()的方法,获取子表对象的list时,Hibernate仍会将逻辑删除掉的对象查询并加载到list中。

这两个问题个人感觉很有难度。请问有没有人有实现的思路呢?
问题补充

hekuilove 写道
我也遇到过类似的问题
我在表里弄了一个delete_flag字段1为未删除 0为删除
但是使用hibernate过后就发现remove了 啥都木有了。
才想起delete_flag木有用了

是啊,要想用逻辑删除就不能调hibernate的remove了。需要在自己的dao里封装delete方法,然后设置数据为删除。
要不然一remove就真的删掉了,数据就木有了。

再补充。。为什么虽然触发器这么麻烦,还是要用触发器,是因为只有他能从运维人员意外的delete sql中挽救你。。

我也遇到过类似的问题
我在表里弄了一个delete_flag字段1为未删除 0为删除
但是使用hibernate过后就发现remove了 啥都木有了。
才想起delete_flag木有用了

为什么不使用触发器来做逻辑删除?

同表的话,uk就用不了了。

我有个想法 但不知道可行不
1.要级联删除的时候,先把多端的集合遍历,然后在把多端的标识符改成已经删除
2.要查询的时候 在hbm文件里面 set标签可以加where条件

对于你的第一个问题啊, 删除一个对象还要相应地删除对应的一个子类Set这时候要用到一个属性cascade="delete" , 这样可以做到级联删除的效果,
我想你做删除的时候,你没有提交事务, Hibernate 默认是不会自动提交事务的, 数据库中的数据是不会被删除的, 所以你查询的时候就会都查出来

至于你的第一个问题,可以考虑在数据库层写触发器
第二,查询的话你可以加条件啊,ds=truea。删除的方法就封装自己的业务逻辑吧。

可能上面没说清楚。
一种方案是对于需要逻辑删除的表,创建一张对应deleted item表,在主表删除的时候,通过触发器移至此表。

在原表通过deleteFlag来做的话,如果表中有需要加uk的column,就做不了了,同一uk字段删除第二次的时候就会挂。

因此在这种时候,cascade由hibernate帮你做,触发器只是帮你完成将删除的数据移至deleted item表。