Reputation: 27899
It is essential to delete an entity from its parent list and the parent from the entity itself before the entity is deleted.
Example (CMT in an EJB) one-to-many from State to City :
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;
}
The statement managedCity.setState(null);
sets the entity's parent to null
. Since it is a managed entity, any changes made to the entity will hit the underlying database. Accordingly, an UPDATE
statement will be generated and state_id
in the database table will be set to null
.
UPDATE db.city SET state_id = ?, row_version = ? WHERE ((city_id = ?) AND (row_version = ?))
bind => [null, 2, 10, 1]
This is quite undesired. In addition to issuing an addition UPDATE
statement, it attempts to set state_id
in the database table to null
which will cause problems, if a NOT NULL
database constraint is enforced against the corresponding column in the database table.
How to correctly remove entity's parent before deleting the entity itself or it is not even required to delete (setting it to null
) the parent before deleting the entity (it would cause problems in some cases. The answer should therefore be, No)?
Upvotes: 4
Views: 1561
Reputation: 154030
In case you have a NOT NULL constraint and a bidirectional association is better to propagate the change from the parent side:
public boolean delete(City city) { // Detached instance.
City managedCity = entityManager.contains(city) ? city : entityManager.merge(city);
managedCity.getState().getCityList().remove(managedCity);
return true;
}
and make sure you cascade the REMOVE operation from Parent to Child:
@OneToMany(cascade = CascadeType.REMOVE)
Setting the parent association to null only works when you have a NULL FK.
Upvotes: 2
Reputation: 11298
You need not delete city from state list.
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;
}
you can delete all the cities when state is removed
class State {
...
@OneToMany(cascade = CascadeType.REMOVE, ...)
private List<City> cityList;
...
}
Upvotes: 1