borinquenkid opened a new issue, #16745:
URL: https://github.com/apache/grails-core/issues/16745
## Problem
With Hibernate 7, removing one element from a set of a unidirectional
`hasMany` deletes every row of that association for the owner, and nothing is
re-inserted. The remaining elements are lost.
```groovy
class Solo {
String name
static hasMany = [roles: Role]
}
class Role { String name }
// solo has roles one and two, saved and flushed
solo.removeFromRoles(one)
solo.save(flush: true)
// reloaded: solo.roles is empty, expected [two]
```
The SQL logged for the flush is a single statement keyed on the owner only,
with no restriction on the element:
```
delete from solo_role where solo_roles_id=?
```
## What I verified
- Reproduced on H2 with a single association on its own join table, so it is
not specific to a table that associations share. The reproduction is
`SharedJoinTableBulkDeleteSpec` in `grails-data-hibernate7/core`, feature
"removing one element of a set on a join table of its own keeps the other
elements".
- The same spec fails on `feat/sql-text-8.0.x`, the base of #16701, which
has none of the shared-table changes, so it is not introduced by #16701.
- It was also reported on Oracle in the review of #16701. I have not run the
other databases. The delete is built by Hibernate's persister, not by dialect
code, so I do not expect it to depend on the database.
- I have not checked the v8.0.0 release or an earlier Grails line.
## Likely cause (not confirmed)
Hibernate identifies the row of a set element to delete by the key columns
plus the element columns that are not nullable. The statement above has no
element restriction, which is what the persister produces when the element
column is nullable. I have not traced where the nullability of the join table's
element column comes from in the Grails binder (the key columns are made
nullable by `CollectionKeyColumnUpdater`; the element is bound through the
many-to-one element binder).
## Why it matters for shared join tables
Two unidirectional `hasMany` associations to the same class that share a
join table (#16701) have element columns that must be nullable when each
association has its own element column, so a fix that makes the element column
`NOT NULL` does not cover that shape. A fix may need a custom delete-row
statement for collections whose element is nullable, or element identification
some other way.
## Tests
Pending features in `SharedJoinTableBulkDeleteSpec`, for a set on its own
table, for associations with a key column each, and for associations with one
shared key column.
--
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]