grails-core icon indicating copy to clipboard operation
grails-core copied to clipboard

Mappings for table with composite key crashes when customizing joinTable key column names

Open scottlollman opened this issue 7 months ago • 2 comments

Expected Behavior

A domain class with a composite key should respect key column name specifications on joinTables.

Actual Behaviour

When setting mappings for a domain class with a composite key, the binder does not accept a definition for all the column names and treats configurations as a single string column name. I can not find any valid configuration that will work.

GrailsDomainBinder appears to convert a list or map to a string and tries to use that as a column name. It produces the MappingException when comparing the joinTable key column count to the composite key column count.

The issue appears to start in bindCollectionSecondPass, around 450, after checking hasJoinKeyMapping. That branch assumes a column name for a single long column is being defined. It may also have issues if the primary key is not a long type column.

Steps To Reproduce

  1. Create a grails application using hibernate 5.
  2. Add a domain class structured like this:
class ExampleDomain {
  String a, b
  Collection<String> cList

  static mapping = {
    id composite:['a','b']
    cList(
      joinTable:[
        name:'example_domain_c_list',
        key:['a_col','b_col'],
        column:'c'
      ]
    )
  }
}
  1. Run the application and get a crash MappingException: Foreign key (FK...example_domain [a_col, b_col])) must have same number of columns as the referenced primary key (example_domain [a,b])

Environment Information

  • Operating System: MacOS 15.4.1
  • Java version: Corretto 11
  • GORM version 8.1.2
  • Grails version: 6.2.0

Example Application

No response

Version

6.2.0

scottlollman avatar May 07 '25 19:05 scottlollman

@scottlollman did you find a solution? Does 6.2.1 or 7.0.0-RC1 resolve this?

jamesfredley avatar Aug 18 '25 22:08 jamesfredley

@jamesfredley I had to go with an alternate model design.

I reviewed the current version of the code in the repo and the relevant code is the same as when I reported the issue. It still uses bindSimpleValue("long"... which converts the key definition to a String.

scottlollman avatar Aug 19 '25 13:08 scottlollman