Hi,
I have a similar problem, using Grails 1.3.2, extended gorm-mapping-plugin is installed.
The three domain objects (BatchDef, Process and Step) below are a simplification of a legacy mapping scenario I find a hard nut to crack (not to say impossible
).
The tables have a composite foreign key relation Step --> Process --> BatchDef.
My intuitive approach was to just map the fields as well as configure the hasMany and the belongsTo settings and be fine. But this seems to be impossible with the current grails release.
Reason: Grails definitively wants to control the names of the foreign key fields (columns). They always get prefixed by the name of the referenced table. I got the nasty "Foreign key (ZZZ [XXX,YYY,ref_tab_XXX,ref_tab_YYY])) must have same number of columns as the referenced primary key (TTTT [XXX,YYY])"-message, because grails adds its own foreign key columns regardless of which I specify.
It's difficult to explain, maybe you understand the behaviour if you take a look at the example below - first as is - and then again but removing the code marked as "workaround" while enabling instead the code lines marked as "original approach".
What I finally did was to create an updateable view for the T_STEP-table where the foreign key columns have been renamed to the ones expected by grails while at the same time marking the foreign key columns as "insertable:false, updateable:false" to avoid the other doomsday message: "Repeated column in mapping for entity: XXX column: YYY (should be mapped with insert="false" update="false")". It structurally works now, as testing with an empty database (let grails create the tables) shows - but I'm not sure if it really matches my expectations in the long run ...
This "solution" looks weird to me somehow and I feel there must be a better way (I'm new to grails) or it is a bug.
Regards.
Karl Eilebrecht
Domain objects:
====================================
class BatchDef {
String batchName
//other attributes
static constraints =
{
sort batchName:"asc"
}
static hasMany = [ processes: Process ]
static mapping = {
id name: 'batchName', generator: 'assigned', type: 'string'
table 'T_BATCH_DEF'
columns
{
batchName column: 'PK_BATCH_NAME'
//other
}
version false
}
}
class Process implements Serializable {
String batchName
String processName
//other attributes
static constraints =
{
sort batchName:"asc", processName:"asc"
}
static belongsTo = [ batch: BatchDef]
static hasMany = [ steps: Step ]
static mapping = {
id composite: ['batchName', 'processName'], generator: 'assigned'
table 'T_PROCESS'
columns
{
batchName column: 'PK_BATCH_NAME'
processName column: 'PK_PROCESS_NAME'
//other
}
batch column: 'PK_BATCH_NAME', insertable:false, updateable:false
version false
}
}
// Here comes the domain object finally working somehow, the physical columns now have the
// the grails names 'process_batch_names' and 'process_process_names' instead of
// names I would like to have 'PK_BATCH_NAME' and 'PK_PROCESS_NAME'.
class Step implements Serializable {
// original approach
// String batchName
// String processName
// end original
// workaround
String processBatchName
String processProcessName
// end workaround
int stepNumber
//other attributes
static constraints =
{
// original approach
// sort batchName:"asc", processName:"asc", stepNumber:"asc"
// end original
// workaround
sort processBatchName:"asc", processProcessName:"asc", stepNumber:"asc"
// end workaround
}
static belongsTo = [ process: Process]
static mapping = {
// original approach
// id composite: ['batchName', 'processName', 'stepNumber'], generator: 'assigned'
// end original
// workaround
id composite: ['processBatchName', 'processProcessName', 'stepNumber'], generator: 'assigned'
// end workaround
table 'T_STEP'
columns
{
// original approach
// batchName column: 'PK_BATCH_NAME'
// processName column: 'PK_PROCESS_NAME'
// end original
stepNumber column: 'PK_STEP_NUMBER'
//other
}
// original approach
// process type: Process,
{
// column name: 'PK_BATCH_NAME'
// column name: 'PK_PROCESS_NAME'
// }
, insertable:false, updateable:false
// end original
// workaround
process type: Process,
{
column name: 'process_batch_name'
column name: 'process_process_name'
}
, insertable:false, updateable:false
// end workaround
version false
}
}
no resolution for this problem?
is a blocker on my project, i really need it
some workaround?