简体   繁体   English

Hibernate:在删除之前检查外键约束违规?

[英]Hibernate: Check foreign key constraint violation before delete?

The system I'm currently working on has a policy in which objects that have no relationships can be freely deleted, while those that do must be logically deleted. 我正在处理的系统有一个策略,其中没有关系的对象可以自由删除,而那些必须在逻辑上删除的对象。 This is meant to prevent historical information from being deleted. 这是为了防止删除历史信息。

So basically, what I was trying to do was determine whether an object's key is currently present in another table. 基本上,我试图做的是确定对象的密钥当前是否存在于另一个表中。 If it isn't I would simply call delete(), otherwise I would set a property that indicates a logical delete, and call update(). 如果不是,我只会调用delete(),否则我会设置一个指示逻辑删除的属性,并调用update()。

I'm using Spring transaction management, so I'm trying to mess with the session itself as least as possible. 我正在使用Spring事务管理,所以我试图尽可能地混淆会话本身。 My initial approach seemed to work at first, but you'll see that it has a major flaw: 我最初的方法似乎首先起作用,但你会发现它有一个重大缺陷:

@Transactional
public void deleteObject(SomeEntity object)
{       
    //try to delete
    this.someEntityDAO.delete(object);

    try //force foreign key constraint check
    {
        this.someEntityDAO.flush();
    }
    catch (ConstraintViolationException e)
    {
        //reload object
        object= this.someEntityDAO.loadById(object.getId());

        //save as inactive instead of deleting
        object.setActive(false);
        this.someEntityDAO.update(object);
    }
}

Since Hibernate exceptions are fatal, this is completely unreliable (even though it works). 由于Hibernate异常是致命的,因此这是完全不可靠的(即使它有效)。 I was wondering if there is a way to do a sort of "peek" operation in which I could test if the delete will fail due to a constraint, without actually performing the operation (and thus invalidating the session). 我想知道是否有办法进行某种“偷看”操作,我可以测试删除是否会因约束而失败,而不会实际执行操作(从而使会话无效)。 The only thing I can think of is to manually check each related table to see if the id is present, but this would be very tedious and error-prone in tables with many relationships. 我唯一能想到的是手动检查每个相关的表以查看id是否存在,但是在具有许多关系的表中这将是非常繁琐且容易出错的。 I want to leverage the constraints that are already in place in the database, if possible. 如果可能,我想利用数据库中已有的约束。

Speaking specifically to: 具体说到:

So basically, what I was trying to do was determine whether an object's key is currently present in another table. 基本上,我试图做的是确定对象的密钥当前是否存在于另一个表中。 If it isn't I would simply call delete(), otherwise I would set a property that indicates a logical delete, and call update(). 如果不是,我只会调用delete(),否则我会设置一个指示逻辑删除的属性,并调用update()。

and: 和:

I was wondering if there is a way to do a sort of "peek" operation in which I could test if the delete will fail due to a constraint, without actually performing the operation (and thus invalidating the session). 我想知道是否有办法进行某种“偷看”操作,我可以测试删除是否会因约束而失败,而不会实际执行操作(从而使会话无效)。

I have only worked occasionally with Hibernate, but the general answer is: This is what SQL is for. 我只偶尔使用Hibernate,但一般的答案是:这就是SQL的用途。 It's all in your where clause! 一切都在你的where子句中!

For clarity: You do your delete with a sufficient where clause that it does the check in the transaction itself; 为清楚起见:您使用足够的where子句进行删除,以便在事务本身中进行检查; The delete deletes whatever it is that meets the constraints given. 删除删除符合给定约束的任何内容。

Update: 更新:

When you write: 当你写:

"So basically, what I was trying to do was determine whether an object's key is currently present in another table. If it isn't I would simply call delete(), otherwise I would set a property that indicates a logical delete, and call update()." “所以基本上,我试图做的是确定一个对象的密钥当前是否存在于另一个表中。如果不是,我只会调用delete(),否则我会设置一个指示逻辑删除的属性,并调用更新()。”

the problem is that YOU are trying to do this when you should let (direct) the database engine to do it for you in your SQL. 问题是,当您应该让(直接)数据库引擎在SQL中为您执行此操作时,您正在尝试执行此操作。 Investigate use of the "not exists" clause... 调查使用“不存在”条款......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM