问题:实体(比如用户)在UI中以分页方式显示.UI还显示针对每个实体的复选框,以便管理员可以多选用户并删除它们.很自然,这个实体通过外键关系与许多其他实体相关联(比如他创建的采购订单)
如果采购订单与某个用户相关联,则由于外键违规,将无法删除用户.类似地,User可能与许多其他此类表有关系.
如果无法删除实体,最好不要显示删除复选框.如果需要进行此类检查,则在为每个用户行构建用户列表页面时,需要查询从属表以查找可能的关系.如果有很多用户,这可能是非常昂贵的事情.
以优雅的方式解决这个问题的建议方法是什么?
我想到了五种方式:
cascade=CascadeType.DELETE(或ALL)声明所有依赖项.然后将删除所有内容,但这很少是所需的行为.在任何地方显示复选框,逐个删除用户(使用session.remove()/ entityManager.remove())并捕获任何用户ConstraintViolationException.就像是:
for (User user : usersToDelete) {
try {
entityManager.remove(user); // or dao.remove(),
// or someService.remove()
} catch (Exception ex) {
// verify if the there is `ConstraintViolationException`
// in the exception chain, and log a short message about the failure
// If the exception is elsewhere, then log the whole exception
// or rethrow
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,您可能需要设置它FlushMode,EntityManager以便在正确的时间抛出异常.
编写特定于数据库的代码,用于检查用户(或同一场景下的任何对象)的约束.我这样做了一次,因为它允许准确显示哪些记录取决于当前记录.我在删除时执行了特定于数据库的检查,因此所有用户都有了复选框.
按照你说的做,但是将所有结果存储在某种缓存中(无论是你自己的缓存还是Hibernate的缓存,你都可以更容易控制).因此,很少进行昂贵的操作.另外,请考虑为用户列表使用分页.
尝试实现ON CASCADE SET NULL.如果有可能,我不会,也许是cascade=ALL+ nullable=true.检查这个帖子.如果您没有从实体生成数据库,那么juts会ON CASCADE SET NULL在数据库中设置它.
还有一个相关的建议:不要使用HQL进行删除,因为它忽略了Hibernate级联.
| 归档时间: |
|
| 查看次数: |
2983 次 |
| 最近记录: |