java - Hibernate:无法级联删除子级的单向父级

标签 java spring hibernate jpa

当删除 child 的 parent (在一对多的单向关系中)时,我不断收到这些错误。 当我先删除 child 时,一切正常。

我不需要/想要双向关系。

这是父级:

@Entity
@Table(name = "datagroup")
public class DataGroup implements java.io.Serializable {
    @Id
    @Column(name = "group_id", unique = true, nullable = false)
    private int         group_id;
    private String      name;

    @OneToMany( targetEntity=DataGroupItem.class, fetch=FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name="group_id")
    private List<DataGroupItem> dataGroupItems = new ArrayList<>( 0);
    ... setters and getters
}

这是 child :

@Entity
@Table(name = "datagroupitems")
public class DataGroupItem implements java.io.Serializable {
    @Id
    @Column(name = "item_id", nullable = false)
    private int item_id;
    private String name;

    @Column(name = "group_id", nullable = false)
    private int group_id = 0; // only for (un)delete
    ... getters and setters
}

当删除 Controller 中的父级时,我这样做:

@RestController
@RequestMapping("/learner/groups")
public class LearnerSyncServices {
    @Autowired
    private IDataGroupRepository dataGroupRepository;
    @Autowired
    private IDataGroupItemRepository dataGroupItemRepository;
    ... 

    @RequestMapping( method= RequestMethod.DELETE, value="/{id}")
    public void delete(@PathVariable String id) {
        try {
            int idx = Integer.parseInt( id);
            dataGroupRepository.delete( idx);
        } catch (Exception e) {
            logger.error( "Cannot delete " + id + "  " + e.getMessage());
        }
    }

作为 JPA 版本,我有:Spring boot 版本 4.1.3。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

删除至少有 1 个子级的组会显示以下消息:

.. WARN  org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState: 23000
.. ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Column 'group_id' cannot be null
.. INFO  org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements
.. ERROR nl.deholtmans.tjm1706.learner.LearnerSyncServices - Cannot delete 101  could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

最佳答案

当删除DataGroup时,hibernate首先尝试发出删除父级的SQL语句,然后继续发出删除子级的语句。

删除父级时,datagroupitems表中的外键必须设置为NULL以保持数据库一致性(此时,对于数据库来说并不明显)子行也将被删除)。但是,它不能设置为 NULL,因为您在架构定义中明确禁止它。

Hibernate 根本不知道它应该首先删除子级,最后删除父级。您可以通过允许 group_id 列可为空来解决此问题。

编辑如果您不使用“hbm2ddl.auto/javax.persistence.schema- Generation.database.action”,请不要忘记重新创建/手动更新您的数据库架构。需要从数据库中删除 NOT NULL 约束才能使此解决方案发挥作用。

关于java - Hibernate:无法级联删除子级的单向父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42191461/

相关文章:

java - persistence.xml 使用 java 配置

spring - MongoDB 有哪些可用的版本控制工具

java - Spring数据jpa deleteBy查询不起作用

hibernate - 面对 `org.hibernate.hql.PARSER`使用executeQuery()方法从Grails中的数据库中获取数据时出错。请告诉我我做错了什么?

java - 将 hashmap 转换为小写

java - Spring以编程方式注册RequestMapping

java - 自定义 Spring AOP 注解不适用于默认方法

java - 在 JSP 中使用从 servlet 传递的变量?

java - Eclipse Java Selenium 无法连接到本地主机

Java Spring : JUnit Hamcrest: Expecting Collection