Hello,
I have Users, Roles and a many-to-many between them (userroles table).
Users have validRoles and Roles have validUsers. Neither hasCascadeType specified. To my surprise, when I delete a Role, itdeletes from userroles as well. The database has cascade "no action"on userroles.roleid and userroles.userid.
Why are records in userroles being deleted?
Thanks.
/Daryl
Yes, sorry I was not clear.
I believe we should change this behavior (and treat this as a bug).
For we did that I wanted to check the JPA 2 spec to see if there was anything we missed wrt the behavior with and without the cascade.REMOVE. It appears nothing around this area has changed in JPA2. The important things to note for users... is that they are going to get different behavior around ManyToMany deletes (with and without cascade.REMOVE) with different vendors which is a shame (and potentially a bit dangerous when you swap vendors).
Behaviour without cascade.REMOVE-----------------------------------------------------The current behavior does delete the intersection rows whether you like it or not.
As Daryl has pointed out - this means we can't handle the cases where you want the delete to not cascade but instead to fail when there are rows in the intersection table (sol).
In changing the behavior we also need to supply a new method deleteManyToManyAssociations(...) so that users can easily explicitly do the deletion from the intersection table if that is the behavior they need. This also is nice as it compliments our saveManyToManyAssociations() method. NB: You can also use cascade REMOVE (or cascade ALL) but then you are relying on vendor (Ebean) specific behavior (and you may not like that or at least need to note it).
Behavior with cascade.REMOVE (should not change)---------------------------------------------------------------------------------Users should note that with cascade.REMOVE or cascade.ALL on a ManyToMany ... they are going to get different behavior from different vendors. I think Ebean should follow its current behavior which effectively means the intersection rows get deleted but the other associated beans DO NOT get deleted.
I believe this makes sense (not to casade the delete across to the associated beans) as ManyToMany typically represents an ASSIGNMENT between two entities with independent life cycles. If users want to delete the beans on the other side of the ManyToMany they can do this easily anyway with Ebean (delete can take an iterator).
(We need to justify our behavior as its up to the vendor what they do here)
So hopefully that is a bit clearer ... all comments welcome... and if we don't get any arguments against we will log a bug and change the behaviour (to not delete from the intersection automatically) and add the deleteManyToManyAssociations(...) method.
... and thanks to Daryl for highlighting this issue !!!
Cheers, Rob.
> Behavior with cascade.REMOVE (should not change)> --------------------------------------------------------------------------- ------> Users should note that with cascade.REMOVE or cascade.ALL on a ManyToMany> ... they are going to get different behavior from different vendors. I think> Ebean should follow its current behavior which effectively means the> intersection rows get deleted but the other associated beans *DO NOT* get> deleted.
+1 for me as I agree.
Fixed in HEAD ... added
/** * Delete the associations (from the intersection table) of a ManyToMany * given the owner bean and the propertyName of the ManyToMany collection. * <p> * This returns the number of associations deleted. * </p> */ public int deleteManyToManyAssociations(Object ownerBean, String propertyName) {