Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete children on update parent?

I have "Parent" and "Child" hibernate entities.

On "Parent" I have a Set<Child> to hold it's children.

When I update the Parent with new children, all works fine: the children are created on "child" table.

But, when I remove one element from the Parent hashset and save, the correspondent child on database is not be deleted.

Here is:

On PARENT (named Workflow):

@OneToMany(orphanRemoval=true, cascade = CascadeType.ALL, mappedBy="workflow", fetch = FetchType.EAGER)
private Set<ActivityDB> activities; 

On Child (named Activity)

@ManyToOne
@JoinColumn(name="id_workflow")
@Fetch(FetchMode.JOIN)
private WorkflowDB workflow;

I'm working on persistent instance inside the session. No error is raised. Just seems to work fine, but the register on database still there.

To do a test, I load the Workflow and do a

workflow.activities.remove( activity_index_x )

and then save the workflow using session.update( workflow ). but the "activity_index_x" still in database and comes to life again when I reload the workflow.

like image 568
Magno C Avatar asked Nov 01 '22 20:11

Magno C


1 Answers

Make sure you go through the manual regarding bidirectional association links.

The best practices include adding the add/remove child methods:

class WorkflowDB {

    public void remove (ActivityDB a) {
        if (a != null) {
            this.activities.remove(a);
            a.setWorkflow(null);
        }
    }

    public void add (ActivityDB a) {
        if (a != null) {
            this.activities.add(a);    
            a.setWorkflow(this);
        }
    }

}

But because you use a Set as the one-to-many side, you need to pay extra attention to equals and hashcode. The best way is to use a business-key for checking equality and for the hash-code algorithm, and never use the database identifier for equals/hashcode, especially in conjunction with hash-like data structures (set/map).

Bidirectional associations are more complicated to manage than unidirectional ones. If you don't really need the one-to-many side, you can remove it and replace it with a query instead. That way you'd have to manage only the many-to-one side.

like image 50
Vlad Mihalcea Avatar answered Nov 08 '22 04:11

Vlad Mihalcea