Hibernate:不能级联删除子单元的父母

时间:2017-02-12 18:24:42

标签: java spring hibernate jpa

当删除子节点的父节点时(以1对多单向关系),我继续收到这些错误。 当我首先删除孩子时,一切正常。

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

这是父母:

@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
}

这就是孩子:

@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
}

在控制器中删除父级时,我执行:

@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启动版本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

1 个答案:

答案 0 :(得分:1)

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

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

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

编辑如果您未使用&#39; hbm2ddl.auto/javax.persistence.schema-generation.database.action' ;,请不要忘记重新创建/手动更新数据库架构。需要从数据库中删除NOT NULL约束才能使此解决方案正常工作。