休眠:不能级联删除单向父亲的子女

问题描述:

当删除孩子的父母(从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 
+0

对该组的引用是'nullable = false'。您或者需要为每个孩子设置一个新的参考,或者使用级联来删除每个孩子(如果需要的话)。 – dognose

+0

你能否详细说明'nullable = false'和你的两个选项?也许最好把它放在答案中(而不是注释) 首选的是级联删除:删除组及其所有的孩子 – tjm1706

+0

你尝试过的CascadeType DELETE_ORPHAN – Turo

当删除DataGroup,休眠首先试图执行SQL语句,将删除父,然后进行到发布删除孩子的声明。

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

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

编辑如果您不使用'hbm2ddl.auto/javax.persistence.schema-generation.database.action',不要忘记重新创建/手动更新您的数据库模式。需要从数据库中删除NOT NULL约束以使此解决方案起作用。

+0

我得到同样的错误,当我在孩子设定为这样:? @Column(名=“group_id”) private int group_id = 0; OR:@Column(name =“group_id”,nullable = true)。 – tjm1706

+0

我知道您在执行更改后重新创建了模式吗? – crizzis

+0

另外,您能解释为什么需要映射到'DataGroupItem'中的'group_id'列首先呢?你声称你不需要双向关系。我试图删除映射或使其'updatable = false'来查看问题是否消失 – crizzis