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

Hibernate 删除实体前,删除其父引用(如果有),hibernate,jpa,eclipselink,jpa-2.1,Hibernate,Jpa,Eclipselink,Jpa 2.1,在删除实体之前,必须从其父列表中删除实体,并从实体本身中删除父实体 示例(EJB中的CMT)从州到市一对多: public boolean delete(City city) { // Detached instance. City managedCity = entityManager.contains(city) ? city : entityManager.merge(city); managedCity.getState().getCityList().remove(ma

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

示例(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
语句,并且数据库表中的
state\u id
将设置为
null

UPDATE db.city SET state\u id=?,row\u version=?其中((城市id=?)和(行版本=?)
bind=>[null,2,10,1]
这是非常不希望的。除了发出addition
UPDATE
语句外,它还尝试将数据库表中的
state\u id
设置为
null
,如果对数据库表中的相应列强制执行
NOT null
数据库约束,这将导致问题


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

您不需要从州列表中删除城市

 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;
 ...
}
类状态{
...
@OneToMany(级联=级联类型.REMOVE,…)
私人名单城市名单;
...
}

如果您有一个非空约束和双向关联,最好从父端传播更改:

public boolean delete(City city) { // Detached instance.
    City managedCity = entityManager.contains(city) ? city : entityManager.merge(city);
    managedCity.getState().getCityList().remove(managedCity);
    return true;
}
并确保将删除操作从父级级联到子级:

@OneToMany(cascade = CascadeType.REMOVE)

只有当FK为空时,才能将父关联设置为空。

我也这么认为。但是您确定在删除实体本身之前不将父引用(
managedCity.setState(null);
)设置为
null
?我一直在浏览一些被强烈推荐的地方。(另一方面,需要从其父列表中删除实体(
City
),因为只有一个
City
正在被删除(而不是它的父
State
),即
cascade=CascadeType.REMOVE
位于未被删除的关系的反面)。因此,我假设断开链接(关系)从关系的任何一侧都是足够的,即从关系的相反一侧的列表中删除实体,或者将实体的父实体本身设置为
null
(如果为null外部)。两者都不是必需的。是吗?创建关联时,需要设置两侧。断开关联时,最好从父级到子级进行级联。在单向mant到一个关联中,您只需删除子级。在双向关联中,如果只断开一个sid,则只有级联才能寻址非空FKs,而没有它e您可以在删除后重新连接子项。