java - 如果外键引用空行而键不可为空,如何不崩溃?

标签 java mysql hibernate

我有这张表“区域”:

编号 |姓名 | parent_id

1 |随便| 100000

其中 parent_id 应该是对 id 的自引用,这意味着该行在地理上属于 100000。

但是由于一开始导入的数据是脏的,所以id为100000的行不存在。

因此在给定的实体中:

@Entity("regions")
public class Region {
    private int id;
    private String name;
    private Region parent;

    ...

    @ManyToOne()
    @JoinColumn(name = "parent_id")
    public Region getParent() {
        return parent;
    }

    public void setParent(Region parent) {
        this.parent = parent;
    }
}

当我用 hibernate 做一个列表时:

    Session session = sessionHandler.getSession(); //gets current session
    Transaction tx = session.beginTransaction();
    try {
        return (List<T>)session.createQuery("FROM regions").list();
    }
    catch(HibernateException ex) {
        ex.printStackTrace();
        if (tx!=null) tx.rollback();
        throw ex;
    }finally {
        sessionHandler.close(); 
    }

它会抛出异常:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [whatever.entities.Region#6046193]

表示 id 6046193 的区域不存在。如前所述,我预计会发生这样的事情。

我的问题是,鉴于我无法将 parent_id 列编辑为可为空,是否有一种方法可以处理此异常,以便系统忽略该异常并让程序继续运行?

最佳答案

您可以尝试将多对一关系的获取类型设置为惰性。

...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
public Region getParent() {
    return parent;
}
...

我想 hibernate 不会在“全选”过程中抛出错误,如果你这样做的话,你可以在第一次调用 getter 时处理错误。

但我不能 100% 确定这是否有效,而且我认为这不是一个很好的解决方案。我真的认为您应该在导入期间/之后清理您的数据。

如果您不清理数据,则必须永远保留代码中问题的解决方法。如果将来有人删除了 fetch = FetchType.LAZY,因为他们认为这会带来更好的性能怎么办?您的应用程序将以意想不到的方式中断,只是因为您的实体没有正确反射(reflect)数据库中的内容。

您说您不能将 parent_id 设置为 null,因为该列不可为 null。但是如何为丢失的 ID 创建虚拟条目呢?您可以在导入脏数据后、首次启动应用程序之前立即执行此操作。

此外,仅将列更改为可为空(假设您暂时可以这样做)无论如何都行不通。您仍然需要清理数据 - 在这种情况下,当具有引用 ID 的行不存在时,您必须将所有 parent_id 设置为 null。

关于java - 如果外键引用空行而键不可为空,如何不崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34625903/

相关文章:

mysql - SQL Join ON 子句对别名的有效引用

java - "java.lang.AbstractMethodError: org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager" hibernate

java - 无法与远程机器上的 MySQL 数据库建立连接

java - 如何在 3 种不同的浏览器中在同一台电脑上并行运行 selenium html 套件?

java - 使用Math.pow在java中对数字进行平方得到精度误差

php 插入不起作用

php - 从 PHP 获取 MySQL 字符串时不相等的二进制字符比较

java - 如何打印二维数组中元素的总和?

java - 如何检查数据库事务中的数据?

hibernate - 如何在Hibernate/JPA中为每个持久单元执行differnet import.sql?