ianroberts opened a new issue, #16691:
URL: https://github.com/apache/grails-core/issues/16691

   ### Expected Behavior
   
   Given a set of domain classes
   
   ```groovy
   // Role.groovy
   class Role {
     String authority
   }
   
   // Item.groovy
   class Item {
     String name
   
     static hasMany = [roles: Role]
   }
   ```
   
   If I have an item with two different `roles` in its hasMany set and I remove 
just _one_ of them, the other one should not be removed.
   
   ### Actual Behaviour
   
   With Grails 8 Hibernate 7, a single `removeFromRoles` (or any equivalent 
operation such as data binding to a subset of the original role IDs) clears the 
_entire_ `roles` list for that `item`.  Hibernate 5 works correctly, and only 
removes the role we asked it to remove.
   
   ### Steps To Reproduce
   
   See my [example 
repository](https://github.com/ianroberts/grails-h7-multiple-hasmany) - this is 
the same app that demonstrated #16665, with a bit more logic added.  When I do 
the following sequence of operations:
   
   ```groovy
   def item = new Item(name: "example")
   def role = Role.findOrCreateByAuthority("ROLE_EXAMPLE")
   item.addToRoles(role)
   item.addToRoles(Role.findOrCreateByAuthority("ROLE_EXAMPLE2"))
   item.save(flush: true)
   ```
   
   both versions of Hibernate create the right things - one row in the item 
table, two in the role table, and two in the join table.  But if I subsequently 
do
   
   ```groovy
   item.removeFromRoles(role)
   item.save(flush:true)
   ```
   
   Hibernate 5 removes just the `ROLE_EXAMPLE` join table row, but Hibernate 7 
removes both.
   
   **Hibernate 5**
   
   ```
   insert into role (id, version, authority) values (default, ?, ?)
   insert into role (id, version, authority) values (default, ?, ?)
   update item set version=?, name=? where id=? and version=?
   insert into item_role (item_roles_id, role_id) values (?, ?)
   insert into item_role (item_roles_id, role_id) values (?, ?)
   Item has roles [ROLE_EXAMPLE, ROLE_EXAMPLE2]
   Remove role 1
   Save and flush
   update item set version=?, name=? where id=? and version=?
   delete from item_role where item_roles_id=? and role_id=?
   ```
   
   **Hibernate 7**
   
   ```
   insert into role (authority,version,id) values (?,?,default)
   insert into role (authority,version,id) values (?,?,default)
   update item set name=?,version=? where id=? and version=?
   insert into item_role (item_roles_id,role_id) values (?,?)
   insert into item_role (item_roles_id,role_id) values (?,?)
   Item has roles [ROLE_EXAMPLE, ROLE_EXAMPLE2]
   Remove role 1
   Save and flush
   update item set name=?,version=? where id=? and version=?
   delete from item_role where item_roles_id=?
   ```
   
   Note that Hibernate 5 includes `and role_id=?` in the where clause of the 
delete statement, but Hibernate 7 does not, therefore it deletes _all_ join 
table rows related to this item ID.
   
   ### Environment Information
   
   - Operating system: macOS Tahoe 26.6.2
   - JDK: Azul Zulu JDK 21
   
   ```
   openjdk version "21.0.12.1" 2026-08-18 LTS
   OpenJDK Runtime Environment Zulu21.52+203-CA (build 21.0.12.1+1-LTS)
   OpenJDK 64-Bit Server VM Zulu21.52+203-CA (build 21.0.12.1+1-LTS, mixed 
mode, sharing)
   ```
   
   ### Example Application
   
   https://github.com/ianroberts/grails-h7-multiple-hasmany
   
   ### Version
   
   8.0.0 (plus the fix for #16665)


-- 
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]

Reply via email to