java - Hibernate 从 4 迁移到 5 OneToOne 关系后导致 ConstraintViolationException

标签 java postgresql hibernate migration

我们有这样的OneToOne双向关系:

class Student:

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(FetchMode.JOIN)
    private StudentState state;

    public Student() {
        super();
        state = new StudentState(this);
    }

    public StudentState getState() {
        return state;
    }

class StudentState:

    @MapsId
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "student")
    private Student student;

    @Column(name = "inactive")
    private Boolean isInactive = false;

    public StudentState() {
    }

    public StudentState(Student student) {
        this.student = student;
    }

    public boolean isInactive() {
        if (isInactive == null) {
            return false;
        }
        return isInactive;
    }

    public void setIsInactive(boolean isInactive) {
        this.isInactive = isInactive;
    }

以及我们用来创建 Student 的以下代码:

Transaction t = session.beginTransaction();

Student student = new Student();
session.save(student);
student.getState().setIsInactive(true);

t.commit();

该代码在 Hibernate 4 中运行良好。 在 Hibernate 5 中,它因 org.hibernate.exception.ConstraintViolationException: could not execute statement 而崩溃 错误。

启用“Show sql”显示在事务提交上,hibernate 尝试在insert Student 查询之前执行insert StudentState 查询。它导致:

Caused by: org.postgresql.util.PSQLException: 
ERROR: insert or update on table "studentstate" violates foreign key constraint "fk77j3mjaigcfotxlor35mdsl56"'
Detail: Key (student)=(12) is not present in table "students".

知道为什么会发生这种情况,为什么它以前有效以及如何解决?时间差

最佳答案

问题的原因是hibernate core的bug。类 org.hibernate.engine.spi.ActionQueue。 这是我修复后的代码:

            boolean hasAnyParentEntityNames(BatchIdentifier batchIdentifier) {
                return parentEntityNames.contains(batchIdentifier.getEntityName())
                        || parentEntityNames.contains(batchIdentifier.getRootEntityName());
            }

            boolean hasAnyChildEntityNames(BatchIdentifier batchIdentifier) {
                return childEntityNames.contains(batchIdentifier.getEntityName())
                        || childEntityNames.contains(batchIdentifier.getRootEntityName());
            }

这是之前的代码:

        boolean hasAnyParentEntityNames(BatchIdentifier batchIdentifier) {
            return parentEntityNames.contains(batchIdentifier.getEntityName())
                    || parentEntityNames.contains(batchIdentifier.getRootEntityName());
        }

        boolean hasAnyChildEntityNames(BatchIdentifier batchIdentifier) {
            return childEntityNames.contains(batchIdentifier.getEntityName())
                    || parentEntityNames.contains(batchIdentifier.getRootEntityName());
        }

有人使用了错误的列表来寻找 child ,在某些情况下该方法返回了相反的值。

关于java - Hibernate 从 4 迁移到 5 OneToOne 关系后导致 ConstraintViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46530846/

相关文章:

java - Spring 数据 JPA : How can Query return Non- Entities Objects or List of Objects?

java - 使用 Hibernate 查询 H2

Java字符串正则表达式匹配失败并换行?

java - 无法实例化默认 tuplizer : HIbernate

java - 当我从未关闭任何结果集时,为什么会出现 ResultSet is closeed 错误

oracle - Golden Gate 复制极度延迟

java - Liferay:如何使邮件不再是交易性的

php - 在数据库迁移中添加一个 `tsrange` 列

mysql - 我的 Web 应用程序需要 mongodb 或 mysql 吗?

java - 最新的 hibernate (5) 是否适用于数组类型?