Spring Data JPA deletions not what I expected

1.9k views Asked by At

I thought I had a better understanding of Spring Data JPA (deletes) until recently.

Anyway, I have two classes with a OneToMany and a ManyToOne relationship:

@Entity
@Table(name = "COMPANIES")
public class Company implements Serializable {
...
        @OneToMany(mappedBy = "company", 
                   fetch = FetchType.EAGER, 
                   orphanRemoval = true, 
                   cascade = CascadeType.ALL)
        private Set<Commodity> commodities = new HashSet<>();
}

....

@Entity
@Table(name = "COMMODITIES")
public class Commodity implements Serializable {
...
        @ManyToOne(optional = false)
        @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false)
        private Company company;
}

I want to delete a Commodity record so I have this in my service layer:

@Transactional
public void delete(Commodity commodity) {
    repo.delete(commodity);
}

When I run the code, it performs all of the SELECT's but it never actually performs the delete. No error messages...no delete in the logs, etc.

So I found I have two options:

1) Remove the CascadeType.ALL

2) Change my delete method to:

@Transactional
public void delete(Commodity commodity) {
    Company company = commodity.getCompany();
    company.getCommodities().remove(commodity);
    companyRepo.save(company);
}

3) Write a custom @Query method to perform delete (rather not).

My understanding of the cascading was that if we were to delete a master record like Company, then all of its child objects would be automatically deleted. That makes sense to me.

So, my question is, why does that CascadeType prevent me from manually deleting a child record?

Thanks

EDIT

I wasn't very clear. Using option 1 or option 2 above does perform the delete.

2

There are 2 answers

1
zmf On BEST ANSWER

This is by design.

When you try to remove a commodity by itself, the owning entity still has record that an instance of a commodity should still exist in the database.

Here is the exact quote from the hibernate doc:

Conversely, if an entity is removed from a collection (a one-to-many or many-to-many association), it will not be deleted by default. This behavior is completely consistent; a change to the internal state of another entity should not cause the associated entity to vanish. Likewise, adding an entity to a collection does not cause that entity to become persistent, by default.

1
JuanGG On

Your database might be preventing you from deleting the records. Check your table definition and to see which kind of constraint you have or try to delete some records directly in the SQL console to see if you get any errors.

Otherwise, take a look to question 306144; hope it helps. More info: here