3

I have ManyToOne relationship between Parent and Child. I want to Delete multiple Child entities that answer a certain query. The problem is that after I run a Delete query, Parent.getChildren() still returns the deleted children.

Can't I use Delete queries in such case?

@Entity
@Table(name = "CHILD_DATA")
public class Child {
    private Parent parent;
}


@Entity
@Table(name = "PARENT")
public class Parent{

    private Set<Child> children;

    @Column(name = "CHILDREN")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public Set<Child> getChildren() {
        return children;
    }

}

public class ChildDAO{

     public int removeServiceFrontPageData(Parent parent, long serviceID){
            String query = "DELETE FROM Child WHERE parent =:parent";
            Query q = em.createQuery(query);
            q.setParameter("parent", parent);
             return q.executeUpdate();
        }
}

To refresh a parent entity, I use the following function:

public class ParentDAO{

    public Parent getParent(String parentID){
        final String select = "FROM Parent WHERE parentID = :parentID";
        Query q = em.createQuery(select);
        q.setParameter("parentID", parentID);
        if(q.getResultList().isEmpty()){
            return null;
        }
        return (Parent) q.getSingleResult();
    }

}

thanks

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
lili
  • 1,866
  • 8
  • 29
  • 50
  • try changing parent.id to just parent, and pass the object itself, not the id. What you have should be working. – hvgotcodes Jun 19 '11 at 13:32
  • I changed to parent, no affect. Notice that q.executeUpdate() returns a number of removed entities, but the parent.getChildren() isn't updated. It probably brings data from cache. – lili Jun 19 '11 at 13:37
  • @lili are you doing the delete in its own session/transaction? also try flushing the session. – hvgotcodes Jun 19 '11 at 13:39
  • I tried adding em.flush(). I added a unit test: first I create parent with children, then I remove children, then I bring parent entity and check its children. The check fails because parent contains removed children. – lili Jun 19 '11 at 13:50
  • ok, isolate the issue. take the serviceId part of the where clause out and see if it works just trying to remove by parent. verify that the service is being set correctly on the child. I notice its not in the code for the Child class – hvgotcodes Jun 19 '11 at 14:17
  • I updated the code (as I wrote in post), still no change. thanks – lili Jun 19 '11 at 14:36
  • can you post your test? something is off here, this should be simple. You are reloading the parent after the delete, right? – hvgotcodes Jun 19 '11 at 15:07
  • Can you post your actual code? What is posted seems to have bugs: Your JPQL: `DELETE FROM Child WHERE parent =:parent` Specifies parameter "parent" not "parentID" Change this line: `q.setParameter("parentID", parentID);` to: `q.setParameter("parent", parent);` – Terrell Plotzki Jun 19 '11 at 16:44
  • I refresh a parent entity, I added the ParentDAO to my post. I suspect that the problem is because cache of parent.getChildren() isn't refresh after the removal of children – lili Jun 20 '11 at 07:09
  • In this [post](http://stackoverflow.com/questions/5792712/jpa-relationship-not-getting-updated-when-children-are-removed) a similar problem is described: **"when ever you delete an entity, the application is responsible for cleaning up any references to that entity."** Probably I should update a parent if I remove children. – lili Jun 20 '11 at 07:41

1 Answers1

5

My solution is based on another post

I found 2 ways to solve it:

1) update a parent if I remove children:

  • select child entities that should be removed.
  • remove these entities from parent.getChildren()
  • delete the children from database

2) add orphanRemoval=true flag on parent.getChildren(). Remove children from set will remove them from database

@Entity
@Table(name = "PARENT")
public class Parent{

    private Set<Child> children;

    @Column(name = "CHILDREN")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    public Set<Child> getChildren() {
        return children;
    }
Community
  • 1
  • 1
lili
  • 1,866
  • 8
  • 29
  • 50