Your simplified version of code (except hasMany
in Bar) works for me without any FK exception. Although I would prefer a different approach to achieve a true one-one bidirectional relationship if I am correct with the parent and child mapping.
Below is my setup which works fine without the FK constraint exception. Note that I have also mentioned in comments how would I achieve true one-to-one bidirectional assuming Foo has one Bar and has one Baz.
class Foo implements Serializable{
String someValue1
String someValue2
String whatever
//True one to one can be achieved by doing as below
//static hasOne = [bar: Bar, baz: Baz]
Bar bar
Baz baz
static mapping = {
id composite: ['someValue1', 'someValue2'], generator: 'assigned'
columns {
bar([:]) { column name: 'some_other_value' }
baz ([insertable:false, updateable: false]) {
column name: 'some_value_1'
column name: 'some_value_2'
}
}
version: false
}
static constraints = {
//baz nullable:true, unique:true
}
}
class Bar {
String someOtherValue
//True one to one can be achieved by doing as below
//Below entry makes the relation bi-directional
//Foo foo
static mapping = {
id generator:'assigned', name:'someOtherValue'
//Optional, added for clarity
someOtherValue column: 'some_other_value'
}
}
class Baz implements Serializable{
String someValue1
String someValue2
String asdf
//True one to one can be achieved by doing as below
//Below entry makes the relation bi-directional
//Foo foo
static mapping = {
id composite: ['someValue1', 'someValue2']
//Optional, added for clarity
someValue1 column: 'some_value_1'
someValue2 column: 'some_value_2'
asdf column: 'asdf'
version false
}
}
class MyTests extends GroovyTestCase {
def fixtureLoader
void setUp() {
fixtureLoader.load {
myBar(Bar, someOtherValue:"shibby")
myFoo(Foo, someValue1:"test", someValue2:"test2",
whatever: "whatever", bar: myBar)
}
}
void testSomething() {
Foo.all.each{println it.properties}
Bar.all.each{println it.properties}
}
}
//Bootstrap Test in Dev mode
new Bar(someOtherValue: 'shibby').save()
new Foo(someValue1:"test", someValue2:"test2",
whatever: "whatever", bar: myBar).save(failOnError: true, flush: true)
Notes
- Above I have used your exact simplified code but the
hasMany
relation in Bar. - Constraints on
Baz
is optional. - Fixtures works as expected.
- Columns are created in Foo as expected.
logSql
showed expected DML.- To witness the table changes, I also BootStraped the same test data in dev mode following a
run-app
. I was able to see the expected table structure with data in it, usingdbconsole
. - Following the general way of one-to-one bidirectional (mentioned as commented code), FKs are created in the child tables [
Bar
andBaz
], so the explicit mapping you provided in the sample code would not hold good. - The question will be more clear if the owning side of the relationship and the rationale behind having
hasMany
in Bar is mentioned.