borinquenkid opened a new pull request, #16686:
URL: https://github.com/apache/grails-core/pull/16686
Fixes #16665.
## Problem
On Hibernate 7, an owner with two or more unidirectional `hasMany`
associations silently loses `addTo*` on flush:
```groovy
class Item {
String name
static hasMany = [roles: Role, tags: Tag]
}
def item = new Item(name: 'Example item').save(flush: true)
item.addToRoles(new Role(authority: 'ROLE_EXAMPLE'))
item.save(flush: true) // no row is written to item_role
```
With one `hasMany` it works, and it works on Hibernate 5.
## Cause
`CollectionKeyColumnUpdater` marked the key of an entity collection
non-updatable whenever the owner had two or more unidirectional to-many
properties. That is the workaround for #10811, where two `hasMany` to the same
class share one join table and each key column must stay nullable. Hibernate
writes no join table rows for a collection whose key is not updatable, so the
rule also discarded the rows of collections that have a join table of their own.
## Change
The key is non-updatable only when another unidirectional to-many property
of the owner uses the same collection table, which is the #10811 case.
Collections with their own join tables keep an updatable key.
## Tests
- `MultipleUnidirectionalHasManySpec` reproduces the report: an element
added to one of two `hasMany` to different classes is found after the session
is cleared, and so are elements added to both.
- `CollectionKeyColumnUpdaterSpec`: the case that expected a non-updatable
key for two `hasMany` to different classes now expects an updatable one, and a
new case covers two `hasMany` to the same class sharing a join table, which
stays non-updatable.
- The new specs fail without the change. The full
`grails-data-hibernate7-core` test run passes except
`SqlRestrictionHibernate7Spec` against Oracle, whose container cannot start
locally.
## Branches
The class is identical on 8.1.x, 9.0.x, 9.1.x and 10.0.x, so this should
merge forward through them. The Groovy conversion of the Hibernate 7 modules
(#16572) carries a hand-ported version of the same change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
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]