borinquenkid opened a new pull request, #16757:
URL: https://github.com/apache/grails-core/pull/16757
Fixes #16691
Based on 8.0.x; independent of the #16701 / #16750 / #16756 stack.
Under Hibernate 7, removing one element of a unidirectional `hasMany` set
(with `removeFrom*`, or by binding a smaller set of ids) deleted every
join-table row of the owner:
```
delete from item_role where item_roles_id=?
```
Hibernate 7 builds the row delete from the key and only those element
columns that are **not nullable**
(`RestrictedTableMutationBuilder.addKeyRestriction`,
`BasicCollectionPersister.applyDeleteRowRestrictions`). The element column of a
GORM join table is nullable, and it has to be when several collections share
the table with a column each. Hibernate 5 restricted by the element, so it got
this right.
**Fix:** a row restriction of our own, as suggested on the issue. No DDL
change.
- `JoinTableCollectionPersister` extends `BasicCollectionPersister`. It
replaces only the row delete, which restricts by the key and every element
column: `... where item_roles_id=? and role_id=?`. A row of a collection of
entities always has its element, so that is safe.
- `GormPersisterClassResolver` gives that persister to sets and bags of
entities in a join table. Lists and maps already delete by their index, and FK
one-to-many collections keep Hibernate's persister.
- It's registered with `putIfAbsent` on `hibernate.persister.resolver`, so a
resolver the application configures is kept.
| Case | Before | After |
|---|---|---|
| set on its own join table, remove 1 of 2 | both rows deleted | other row
stays |
| roles `[a, b, c]` → `[c, d]` (the issue's comment) | `[d]` | `[c, d]` |
| bag, bidirectional many-to-many, list | unchanged | unchanged |
**Tests**
- New `JoinTableCollectionPersisterSpec` (9):
- which persister each kind of association gets;
- a resolver the application configures is kept;
- the issue's `[a, b, c]` → `[c, d]` case;
- bag and many-to-many removal still work.
- Mutation-checked: with the registration disabled, the set removal and
persister features fail.
- Full `grails-data-hibernate7-core` suite passes locally.
**Merge order with #16701:** #16701 marks three shared-join-table removals
`@PendingFeature` for this issue. With both merged they pass, so
`@PendingFeature` fails them. Whichever of the two merges second drops those
three markers. I verified this on the stack locally:
`SharedJoinTableBulkDeleteSpec` 10/10.
Docs: upgrade note in `upgrading80x.adoc`.
https://claude.ai/code/session_01MDHn7fC3hsGJ27vFHD2o1p
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]