borinquenkid opened a new pull request, #16756: URL: https://github.com/apache/grails-core/pull/16756
Fixes #16700. Stacked on #16750 (it builds on the shared join table uniqueness of #16701 and the Db2 rules of #16750); retarget to `8.0.x` once those merge. ## Problem Two unidirectional `hasMany` lists (or maps) to the same class that share one join table could not be saved: ``` NULL not allowed for column "ROLES_IDX"; SQL statement: insert into owner_role (owner_deny_roles_id, deny_roles_idx, role_id) values (?, ?, ?) ``` Hibernate keys the join table of a list or a map with a primary key over its key and index columns (`IndexedCollection.createPrimaryKey`). On a shared table the next collection replaces it with its own, and it makes those columns `NOT NULL`, while a row of one list leaves the other list's columns null. ## Change `SharedJoinTableUniqueKeyBinder`, for each list or map of a shared table: makes its key and index columns nullable, drops that primary key, and gives it a uniqueness of its own over its key and index columns through `SharedJoinTableUniqueness`, the same per-database rules sets get: | Database | Two lists with a key column each | Two lists with one shared key column | |---|---|---| | H2, PostgreSQL, MySQL, MariaDB | a unique key per list | a unique key per list | | Oracle, Db2 LUW | a unique key per list | one unique key over the key column and both index columns | | Db2 for IBM i and z/OS | — | a `create unique where not null index` per list | | SQL Server | — | a filtered unique index per list | A position or a map key is taken once; an element may repeat, as a list allows. On Oracle and Db2 LUW `SharedJoinTableUniqueness` now creates the key when there is none to widen, since a list has no implicit unique key (a set always has one, so sets are unchanged). ## Tests - `SharedJoinTableListHibernate7Spec` (new): both shapes keep their lists in order; removing from one list keeps the other and the order of the rest; an element may repeat and clearing one list keeps the other; two maps keep their entries. A container feature writes and reads both shapes on H2, PostgreSQL, MySQL, MariaDB, Oracle and Db2 (CI, amd64), and checks that a second row at a taken position is rejected; with the uniqueness removed every database accepts it. - `SharedJoinTableUniqueKeyBinderSpec`: the DDL of two shared lists on H2, Oracle, Db2 LUW, IBM i and SQL Server (55/0). - Full `grails-data-hibernate7-core` suite locally: 4293 tests, 0 failures (the shared `DatabaseContainers` of #16750 makes the Oracle rows pass locally too). Not covered: a set that shares a join table with a list. ## Docs The shared join table note of the 8.0.x upgrade guide, with the migration a schema created by an earlier Grails 8 release needs (drop the primary key, make the index columns nullable; `dbCreate: update` changes neither), and the one-to-many chapter. 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]
