1

In my project I have the classes reported below, with a bidirectional relationship mapping. When I try to delete the parent of the relationship (in my case DataProvider), the main object is deleted, while the children do not get deleted. I have also already tested several other combinations of annotations, none of which seem to work (orphanRemoval, @ElementDependent, optional = false, ...).

Delete is done via a query like this:

Query q = em.createQuery("DELETE FROM DataProvider dp WHERE ... ");
q.executeUpdate(); 

Anyone can please suggest something?

@Entity(name = "DataProvider")
public class DataProviderImpl implements DataProvider {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    // ...

    @OneToMany(targetEntity=RestMethodImpl.class, fetch=FetchType.LAZY, mappedBy="dataProvider", cascade={CascadeType.PERSIST,CascadeType.REMOVE})
    private List<RestMethod> methods;


    public DataProviderImpl() {
        super();
        this.id = 0;
    }

    @Override
    public int getId() {
        return id;
    }
    @Override
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public List<RestMethod> getMethods() {
        return methods;
    }
    @Override
    public void setMethods(List<RestMethod> methods) {
        this.methods = methods;
    }
}

.

public interface DataProvider {
    public int getId();
    public void setId(int id);
    public String getName();
    public void setName(String name);
    public List<RestMethod> getMethods();
    public void setMethods(List<RestMethod> methods);
}   

.

@Entity(name = "RestMethod")
public class RestMethodImpl implements RestMethod {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String nickname;
    // ...

    @ManyToOne(targetEntity=DataProviderImpl.class, fetch=FetchType.LAZY)
    @JoinColumn(name="dataProviderId")
    private DataProvider dataProvider;

    public RestMethodImpl() {
        super();
        this.id = 0;
    }

    @Override
    public int getId() {
        return id;
    }
    @Override
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String getNickname() {
        return nickname;
    }
    @Override
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    @Override
    public DataProvider getDataProvider() {
        return dataProvider;
    }
    @Override
    public void setDataProvider(DataProvider dataProvider) {
        this.dataProvider = dataProvider;
    }
}

.

public interface RestMethod  {
    public int getId();
    public void setId(int id);
    public String getNickname();
    public void setNickname(String nickname);
    public DataProvider getDataProvider();
    public void setDataProvider(DataProvider dataProvider);
}

.

DocDbg
  • 427
  • 1
  • 5
  • 13
  • 1
    possible duplicate of [JPA: DELETE WHERE does not delete children and throws an exception](http://stackoverflow.com/questions/7825484/jpa-delete-where-does-not-delete-children-and-throws-an-exception) – Smutje Jan 26 '15 at 13:47
  • possible duplicate of [JPA OneToMany not deleting child](http://stackoverflow.com/questions/2011519/jpa-onetomany-not-deleting-child) – Naili Jan 26 '15 at 13:49
  • Well it actually looks similar to the first link (the DELETE WHERE issue), even if in my case does not throw any exception. I think I should follow suggestion of that thread anyway.. – DocDbg Jan 26 '15 at 13:51
  • From what I can see, you are specifying that RestMethodImpl is the owner of the relationship, since DataProviderImpl states that the relationsship is mapped by (and thus owned) by the other side. – Tobb Jan 26 '15 at 13:59

1 Answers1

0

Thanks to @Smutje link I changed the query to the following (which worked):

Iterator itr = itemsToDelete.iterator();
int deleted = 0;
while(itr.hasNext()) {
    em.remove(itr.next());
    deleted++;
}

Unfortunately it may not be very fast for bulk delete, but at least for simple delete queries it cascades properly.

DocDbg
  • 427
  • 1
  • 5
  • 13