休眠:不能级联删除单向父亲的子女
问题描述:
当删除孩子的父母(从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
答
当删除DataGroup
,休眠首先试图执行SQL语句,将删除父,然后进行到发布删除孩子的声明。
删除父项时,datagroupitems
表中的外键必须设置为NULL
以保持数据库一致性(此时,对于db来说子数据行也将被删除并不明显)。但是,它不能设置为NULL
,因为您在模式定义中专门禁止它。
Hibernate根本就不知道应该先删除孩子,最后是父母。您可以通过允许group_id
列可以为空来解决此问题。
编辑如果您不使用'hbm2ddl.auto/javax.persistence.schema-generation.database.action',不要忘记重新创建/手动更新您的数据库模式。需要从数据库中删除NOT NULL
约束以使此解决方案起作用。
对该组的引用是'nullable = false'。您或者需要为每个孩子设置一个新的参考,或者使用级联来删除每个孩子(如果需要的话)。 – dognose
你能否详细说明'nullable = false'和你的两个选项?也许最好把它放在答案中(而不是注释) 首选的是级联删除:删除组及其所有的孩子 – tjm1706
你尝试过的CascadeType DELETE_ORPHAN – Turo