3

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.

Rihards
  • 10,241
  • 14
  • 58
  • 78

1 Answers1

2

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.

Affe
  • 47,174
  • 11
  • 83
  • 83
  • Thank you! Yes, that is exactly what I want. If i add the cascade configuration to `@OneToMany` as you said then I don't need to add anything in the `Inventory` entity regarding to cascading, do I? – Rihards Jun 22 '11 at 17:12
  • Well the OneToMany is in the Inventory entity :) You don't need to add anything to the ManyToOne that maps Inventory onto InventoryPreference, no. I think that's what you meant. – Affe Jun 22 '11 at 17:16
  • Thank you, thank you again! You saved my day from hourly long reading and trying to understand the Hibernate reference which is a nightmare! :) – Rihards Jun 22 '11 at 17:19
  • Also note that the orphanRemoval is a JPA 2 feature. If you're on JPA1/Hibernate 3.3.X or earlier, you need to use H specific annotation @Cascade(DELETE_ORPHAN) – Affe Jun 22 '11 at 17:20
  • Yup, I'm on Hibernate 3.6 with JPA2. Thanks tho. One more thing, I've a another entity which holds the identifier of `Inventory` but I don't have a set with it in the inventory entity like I do with `InventoryPreference` above. How do I get it deleted in runtime when `Inventory` gets deleted? It uses `@ManyToOne` in the that entity to get the `Inventory` there. Currently I just run a while statement to get each of those objects linked with the `Inventory` which is going to be deleted and delete each of them. – Rihards Jun 22 '11 at 18:00
  • I don't know of any way to automate that without mapping the collection onto the Inventory, sorry :( – Affe Jun 22 '11 at 18:07
  • Okay, but would it be possible to put any cascading in the parent of the another entity? As I wrote above I've `Inventory` (parent) and `InventoryPreference` (child) and then there is `User` (parent) and `UserCustomizations` (child). The `User` entity has a set of `UserCustomizations` in it and each customization is linked with `Inventory` using `@OneToMany` and `User` (parent). Is seems to me that here it would be possible to make automatic deleting of customization when `Inventory` is deleted, isn't it? – Rihards Jun 22 '11 at 18:25
  • I hope my comment makes sense. I tried to explain the structure clearly as possible. :p – Rihards Jun 22 '11 at 18:25
  • If I understand properly, you would need to have the ManyToOne from Inventory to UserCustomization mapped on Inventory (sounds more like a ManyToMany really?) – Affe Jun 25 '11 at 01:07