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
Java 如何在删除前检查对象是否被引用_Java_Hibernate - Fatal编程技术网

Java 如何在删除前检查对象是否被引用

Java 如何在删除前检查对象是否被引用,java,hibernate,Java,Hibernate,我使用Hibernate开发了具有web界面的java应用程序(SpringMVC)。我这里有一个非常简单的DB方案,有一个组实体,你可以在一个网页上添加/删除。然后还有另一个实体将组作为字段,因此该实体具有FK to Group。请注意,通常可能有许多其他实体引用我的组 如果我想删除组对象,它可能会在FK约束下失败-该组被其他实体引用 是否有一种方法可以在我的组被引用且删除将失败时执行检查,而不是执行删除并捕获异常?这里的最佳实践是什么 谢谢 注意:需要明确的是,简单选择不是解决方案,因为该组

我使用Hibernate开发了具有web界面的java应用程序(SpringMVC)。我这里有一个非常简单的DB方案,有一个组实体,你可以在一个网页上添加/删除。然后还有另一个实体将组作为字段,因此该实体具有FK to Group。请注意,通常可能有许多其他实体引用我的组

如果我想删除组对象,它可能会在FK约束下失败-该组被其他实体引用

是否有一种方法可以在我的组被引用且删除将失败时执行检查,而不是执行删除并捕获异常?这里的最佳实践是什么

谢谢


注意:需要明确的是,简单选择不是解决方案,因为该组通常可能会被许多其他表引用,而不仅仅是一个表。

您可以基于组的ID对实体执行
选择计数
,然后仅在返回值为0时尝试删除组


用try/catch包围删除有什么问题?

删除前检查效率较低,如果在检查和删除之间的另一个事务添加了某个链接,则仍可能导致违反约束

另一方面,它允许向用户显示更具体的错误消息(如“FooBar仍然引用该组”)

在你的具体情况下,做你认为最好的事情。但是请注意,如果发生了某些异常,则应回滚整个事务,并关闭会话,因为此类异常会使会话处于不一致的状态。此外,引发异常的不是delete,而是flush或commit


现在,如果你想检查,没有神奇的解决方案。您可能具有双向关联,因此可以检查
group.getUsers()
是否为emtpy(尽管这将获取组中的所有用户)。或者,您可以从user user where user.group=:group执行专用查询,如
选择count(user.id),以了解该组是否仍然被引用。但是您需要为每个可能的组引用执行其中一个操作。

使用JPA时,您的domainobject组中通常也应该有引用集合。因此,在删除组之前,您可以检查所有这些集合是否为空。但请记住,这可能会在删除之前花费一些额外的时间,但在删除失败时,可能需要通知用户当前关联的对象。

这就是为什么我写了“它可能会被许多其他不同的实体引用”。它可能会从其他6个表中引用,这将使chceck难以执行和维护。。。ConstraintViolationException类似于链中的第四个原因。在我看来,重复这些原因是不对的。在我看来,这绝对不是最佳实践:)所以你们的意思是,你们还有6个表可能有外键指向组?有可能把这些表格归一化吗?这是一个普遍的问题,也许我的例子不是最好的。设想该模式已优化。仍然可以有许多表引用我的单个组。如果我从其他6个表引用了“组”,该怎么办?那么无论是查询还是双向解决方案似乎都不好。。。所以您建议执行删除并处理异常?正如我所说的,您需要为每个引用(用户、foo、bar等)执行删除并处理异常。如果异常比无异常更频繁,并且如果您需要告诉用户哪个实体仍然引用该组,那么我将进行检查。如果您只需要一些通用的错误消息,我会选择例外情况。+1目前为止,但尚未解决-我肯定希望有一些更具体的消息。抛出的异常是JpaSystemException——说明不了多少。这条信息将以一种方式传达给将军。ConstraintValidationException类似于链中的第四个原因。。。如果我能说“无法删除,因为对象被引用了”,我会很高兴,不必告诉谁引用了它。@Jan,为什么不能专门捕获ConstraintViolationException并返回该情况下的错误消息?这实际上是另一个超级问题:)异常从spring转换为JPASystemException。原因是:JPASystemException->PersistenceException->CinstraintValidationException。它被错误地翻译成了这个一般的异常。。。我搜索了几个spring论坛,这本身就是一个大问题。如果我把它翻译成特定的Spring异常,我会很高兴的,为什么我应该有反向的集合?除了检查引用是否存在之外,还有什么好处?检查将加载DB中的所有集合,出于检查目的,这些集合似乎“昂贵”jsut。是的,idd可能很昂贵。这并没有明显的优势,除非您经常需要这些引用,甚至可能需要在实体加载时急切地获取它们,这意味着您已经加载了这些信息。就像尼泽特已经指出的那样。这取决于你的要求。当你需要为用户提供这些详细信息时,你可能不会同意。否则你只会返回一些一般性的错误信息。你找到一个好的解决方案了吗?我也有同样的案子。