-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DDC-130: Cascading and @ManyToMany associations is broken #1913
Comments
Comment created by romanb: I think in most cases the entry in the association table should be deleted by the FK constraint. However I think that is currently not the default. You can force it by using onDelete="CASCADE" on the @joincolumn definitions inside the @jointable. That should probably be set by default on join columns on an association table. I'm not sure its worth supporting manual deletion of association table entries through Doctrine as all databases support proper foreign key constraints and this is the most effective way to delete these entries and also enforces the integrity on the database side. So I'm rather voting for making onDelete="CASCADE" the default for join columns of association tables unless specified otherwise. |
Comment created by romanb: It appears that this doesnt work in JPA(2) either, or well, it depends on the implementation provider. But cascade=REMOVE on @manytomany is not allowed per the spec. This issue here is probably one of the reasons for this. Meaning there might be no easy way for the ORM to deal with entries in association tables transparently on cascade=REMOVE. We have the following options:
Waiting for feedback. |
Comment created by @beberlei: Hm after thinking about it the problem is that the collection has to be either:
|
Comment created by nicokaiser: Hm, I don't know if my report was unclear... What I meant was automatic update of the join table ("user_alert" in this example). When I delete e.g. a User, I don't want to have to care about updates in the "user_alert" table - this table was automatically generated (by the @jointable statement), so it should be automatically updated, e.g. when I delete either a User or an Alert... |
Comment created by alex: How about removing a relation between a user and an alert? Meaning the user and alert both remain in the database but they are not connected anymore (think about users with multiple roles). |
Comment created by romanb: @alexander: Just like in normal OOP. If a user as a collection of alerts and an alert a collection of users (bidirectional many-many) and you want to remove an alert from a user you simply remove the alert from the collection and the user from the collection of the corresponding alert. This is very clean, the only problem with this is the efficiency because in order to remove the elements from the collections, the collections must be loaded. (Strictly speaking, you only need to adjust the "owning side", so only 1 collection needs to be loaded). Of course you can always use some custom SQL that directly manipulates the intermediate table. See also DDC-128. Also there is DDC-45 but I dont think thats doable. Collections of entities always only represent the association of the entity that has the collection and the contained entities. If you remove an entity from a collection, the association is removed, not the entity itself. "The association is removed" means that either the foreign key is NULLed out (in the case of one-to-many) or that the entry in the association table is removed. |
Comment created by alex: @roman: All sounds very simple. But in practice this doesn't seem to work.
Now, when I clear the manager and reload the user:
|
Comment created by romanb: @alexander: Please open a separate issue for this. Thanks. |
Comment created by mjh_ca: Pastebin entries have expired and this bug is not attached to a specific version so it is difficult to tell the status. Nico, is this still a problem with the current release? |
Comment created by romanb: My currently proposed solution to this would be to simply make onDelete="CASCADE" the default for join columns in join tables. Anyone has a strong objection or better idea? |
Comment created by @beberlei: sounds good to me |
Comment created by @beberlei: Other tools actually delete the related records manually, no cascading involved. Since Sqlite doesn't even support foreign keys we should probably do the same instead of relying on "onDelete"="cascade". Whats your take roman? |
Comment created by @beberlei: We have to support this anyways for the following reason: Doctrine 2 gives you absolutely no access to the many-to-many join table, i.e. to be working with cascade it should not only be the default, but the only option (since other options don't work). We need to extend the way "delete" works inside each persister to also clean up many-to-many tables. We need this mechanism anyways for Element Collections to delete all the related entries. The option onDelete="cascade|noaction" is therefore only a hint for the persisters to decide if they perform this action themselves, or let the database vendor perform it. |
Comment created by @beberlei: I pushed my proposed changes to a feature branch: http://github.com/doctrine/doctrine2/tree/[DDC-130](http://www.doctrine-project.org/jira/browse/DDC-130) There are definatly refactorings that need to be done, however in that state its currently doing its job very well. |
Comment created by @beberlei: What about DQL DELETE?
For each join table:
Can this be done determinstically? |
Comment created by @beberlei: The DQL stuff is just way to much to add. Foreign Key constraints should fail in these cases imho |
Comment created by romanb: I think we have to do this on bulk deletion then, too. Examples from EclipseLink:
|
Comment created by @beberlei: Fixed in master using the following semantics:
Tested against normal entities, self-referential, CTI and STI, from the owning and the inverse side. |
Issue was closed with resolution "Fixed" |
Jira issue originally created by user nicokaiser:
I have two Entities: Users and Alerts. They are associated with @manytomany, the assiciation table should be "user_alert".
Entities:
http://pastebin.com/m7bca724a
Sample code:
http://pastebin.com/m4e530f42
The "remove" command in the sample code deletes the user entry and alert entry, but not the user_alert entry (which was automatically created though). This leaves an orphan entry (or the DBMS will complain because of FK constraints).
The user_alert table should be automatically updated (on creation and removal)...
The text was updated successfully, but these errors were encountered: