I can't delete a child object from the database. From the org.apache.struts.action.Action.execute()
method, I am removing the child from the parent's List
, and also calling session.delete(child)
. I've simplified the code below and only included what I believe to be relavent.
<class
name="xxx.xxx.hibernate.Parent"
table="parent">
...
<list
name="children"
cascade="all,delete-orphan"
lazy="true"
inverse="true">
<key column="parent_id"/>
<index column="list_index"/>
<one-to-many class="xxx.xxx.hibernate.Child"/>
</list>
</class>
<class
name="xxx.xxx.hibernate.Child"
table="child">
...
<many-to-one
name="parent"
class="xxx.xxx.hibernate.Parent"
not-null="true"
column="parent_id" />
</class>
Transaction tx = session.beginTransaction(); //session is of type org.hibernate.Session
try {
Parent parent = (Parent) session.get(Parent.class, getParentId());
Iterator i = form.getDeleteItems().iterator(); //form is of type org.apache.struts.action.ActionForm
while(i.hasNext()){
Child child = (Child) i.next();
session.delete(child);
parent.getChildren().remove(child); //getChildren() returns type java.util.List
}
session.saveOrUpdate(parent);
tx.commit();
} ...
I've tried with only session.delete(child);
and I've tried with only parent.getChildren().remove(child);
and with both lines, all without success. There are no errors or thrown exceptions or anything of the sort. I'm sure this code gets called (I've even used System.out.println();
to trace what's happening), but the database isn't updated. I can add children using similar code, edit non-collection properties of existing children, edit the parent's properties, all of that works, just not deleting!
According to the Hibernate FAQ I'm doing the mapping right, and according to this SO question I've got the right logic. I've looked all over the internet and can't seem to find anything else.
What am I doing wrong? Please help! Thanks.
Everything is a few years old:
An element can be removed from a Collection using the Iterator method remove(). This method removes the current element in the Collection. If the remove() method is not preceded by the next() method, then the exception IllegalStateException is thrown.
In Hibernate, an entity can be removed from a database by calling the Session. delete() or Session. remove(). Using these methods, we can remove a transient or persistent object from datastore.
To delete a record from database, EntityManager interface provides remove() method. The remove() method uses primary key to delete the particular record.
If you haven't overridden the equals()
method, the entity is probably not found in the list, because it has been detached, and is now a different instance. That's why the remove
isn't working. Then even if the delete
works, the objects are re-cascacde because they still exist in the collection. Here's what to do:
equals()
(and hashCode()
) method(s), using either the id
(easy) or some sort of busines key (more appropriate) (search stackoverflow for tips for overrideing these two metods), and leave only getChildren().remove(child)
Iterate over the collection of children in the first loop, like this:
Iterator<Child> i = form.getDeleteItems().iterator();
while(i.hasNext()){
Child child = i.next();
for (Iterator<Child> it = parent.getChildren().iterator();) {
if (child.getId().equals(it.next().getId()) {
it.remove(); // this removes the child from the underlying collection
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With