Many-to-Many relationships cannot be cleaned up inside beforeDelete()
- Dominant language
- Groovy
- Stars
- 2.9k
- Forks
- 975
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 92
Description
### Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
### Steps to Reproduce
1. Create domain classes with a many-to-many relationship
2. Attempt to clean up the generated join table inside of the `beforeDelete()` method (utilizing `withNewSession` as outlined here: http://gorm.grails.org/6.0.x/hibernate/manual/#_the_beforedelete_event)
3. Attempt to delete one side of the relationship
### Expected Behaviour
The `beforeDelete()` method is able to remove the object being deleted from other associations in the database.
### Actual Behaviour
An exception is thrown when the session is flushed:
```
Hibernate operation: could not execute statement; SQL [n/a]; Referential integrity constraint violation: "FKGHKKY8WMH379RPMFH92T807RY: PUBLIC.TEAM_MEMBERS FOREIGN KEY(PERSON_ID) REFERENCES PUBLIC.PERSON(ID) (1)"; SQL statement:
delete from person where id=? and version=? [23503-194]; nested exception is org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKGHKKY8WMH379RPMFH92T807RY: PUBLIC.TEAM_MEMBERS FOREIGN KEY(PERSON_ID) REFERENCES PUBLIC.PERSON(ID) (1)"; SQL statement:
delete from person where id=? and version=? [23503-194]
```
### Notes
Following the advice from [GORM Gotchas (Part 2)](https://spring.io/blog/2010/07/02/gorm-gotchas-part-2/) I understand that many-to-many relationships do not cascade deletions, so I need to manage them on my own. The domain's `beforeDelete()` method seemed like the perfect place to document this and other side-effects of deleting an instance.
If this is not possible I think there should be a section in the documentation that explains a recommended way of cleaning up associated join tables for many-to-many relationships. I think this situation is common enough to warrant it. I don't mind writing that section if it's confirmed that the sample project exhibits correct behavior.
### Environment Information
- **Operating System**: Ubuntu MATE 17.10
- **GORM Version:** 6.1.8.RELEASE, 6.0.13.RELEASE
- **Grails Version (if using Grails):** 3.2.12
- **JDK Version:** `openjdk version "1.8.0_162"`
### Example Application
- https://github.com/joemccall86/cascade-delete-test/tree/automatic-collection-purge
- Specifically the `automatic-collection-purge` branch
Contributor guide
Research direction
Start with the linked example application's automatic-collection-purge branch and reproduce the failure through the domain beforeDelete() method. Read the referenced GORM beforeDelete documentation and inspect the flush-time referential-integrity exception. Done means the many-to-many join-table cleanup behavior is corrected or a documented recommended cleanup approach is established.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100