Search code examples
javahibernatehibernate-cascade

Trying to understand difference in CascadeType.ALL vs. @OnDelete!


Let me get my question straight, using the @OnDelete here will delete this and any other InventoryPreference entities if the Inventory entity is deleted? I just can't understand a thing from Hibernate's annotations reference.. so I need your help to confirm that I understood it correctly.

public class InventoryPreference {
    ...

    @ManyToOne
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name = "inventory_id", nullable = false)
    public Inventory getInventory() {
        return inventory;
    }
}

Do I then in the Inventory entity need to use CascadeType.ALL too to get all the InventoryPreferences deleted if the Inventory entity is deleted?

public class Inventory {
    ...

    @OneToMany(mappedBy = "inventory", cascade = CascadeType.ALL)
    public Set<InventoryPreference> getPreferenceItems() {
        return preferenceItems;
    }
}

If the first question is true, then I don't see the point of CascadeType.ALL. If it's not then what do each of these do and what annotations and configuration I need to specify to get the InventoryPreferences deleted when Inventory is deleted? Oh and I don't want the Inventory to be deleted if InventoryPreference gets deleted. Sorry if it's too obvious.


Solution

  • They do somewhat different things. @OnDelete is a schema generation instruction. It will add 'on delete cascade' to the end of the DDL generated for the foreign key (or dialect equivalent.) If you're not using hibernate to generate your database, it isn't going to do anything.

    The cascade property on the @OneToMany or @ManyToOne is what's used at runtime to generate additional actual SQL statements. That's probably what you actually want, additional delete statements to remove the children, not delete cascades turned on in the database table? If what you want is for InventoryPreferences to get removed when you delete an Inventory, then you want:

    @OneToMany(mappedBy = "inventory", cascade = CascadeType.REMOVE, orphanRemoval=true)
    public Set<InventoryPreference> getPreferenceItems() {
        return preferenceItems;
    }
    

    And of course add additional Cascade Types as appropriate to your design.