在删除实体之前,删除其父引用(如果有)

Before deleting an entity, deleting its parent reference(s), if any

在删除实体之前,必须从其父列表中删除实体,并从实体本身中删除父项。

示例(EJB 中的 CMT)从州到城市的一对多:

public boolean delete(City city) { // Detached instance.
    City managedCity = entityManager.contains(city) ? city : entityManager.merge(city);
    managedCity.getState().getCityList().remove(managedCity);
    managedCity.setState(null);
    entityManager.remove(managedCity);
    return true;
}

语句 managedCity.setState(null); 将实体的父级设置为 null。由于它是一个托管实体,因此对该实体所做的任何更改都会影响底层数据库。相应地,将生成一条UPDATE语句,并将数据库table中的state_id设置为null

UPDATE db.city SET state_id = ?, row_version = ? WHERE ((city_id = ?) AND (row_version = ?))
bind => [null, 2, 10, 1]

这是非常不受欢迎的。除了发出附加 UPDATE 语句外,它还尝试将数据库 table 中的 state_id 设置为 null,如果 NOT NULL 数据库约束针对数据库中的相应列强制执行 table.

如何在删除实体本身之前正确删除实体的父级,或者甚至不需要在删除实体之前删除(将其设置为null)父级(在某些情况下会导致问题。因此,答案应该是 No)?

您无需从州列表中删除城市。

 public boolean delete(City city) { // Detached instance.
    City managedCity = entityManager.contains(city) ? city :    entityManager.merge(city);
    //managedCity.getState().getCityList().remove(managedCity);
    //managedCity.setState(null);
    entityManager.remove(managedCity);
    return true;

}

您可以在删除状态时删除所有城市

class State {
 ...
  @OneToMany(cascade = CascadeType.REMOVE, ...)
  private List<City> cityList;
 ...
}

如果您有 NOT NULL 约束并且双向关联更适合从父端传播更改:

public boolean delete(City city) { // Detached instance.
    City managedCity = entityManager.contains(city) ? city : entityManager.merge(city);
    managedCity.getState().getCityList().remove(managedCity);
    return true;
}

并确保将 REMOVE 操作从父级级联到子级:

@OneToMany(cascade = CascadeType.REMOVE)

仅当您拥有 NULL FK 时,将父关联设置为 null 才有效。