Grails中的Fixtures插件引用完整性异常

Grails中的Fixtures插件引用完整性异常,grails,one-to-one,fixtures,referential-integrity,bidirectional,Grails,One To One,Fixtures,Referential Integrity,Bidirectional,我有一个对象Foo,它与Bar和Baz有双向一对一关系。当我尝试用Foo进行.load并只给它一个Bar时,我会遇到引用完整性异常,抱怨没有Baz 果真如此吗?在现实环境中,数据库中不可能没有任何匹配的Baz对象吗 我尝试在fixtures加载闭包中手动设置baz:null,但仍然得到相同的结果。另一方面,当我只设置属性(比如一个简单的字符串)时,一切正常。只有当我开始建立关系的时候 这是Grails2.2.4、Fixtures 1.2的版本,并且没有安装构建测试数据插件 编辑:我有一些约束条件

我有一个对象Foo,它与Bar和Baz有双向一对一关系。当我尝试用Foo进行.load并只给它一个Bar时,我会遇到引用完整性异常,抱怨没有Baz

果真如此吗?在现实环境中,数据库中不可能没有任何匹配的Baz对象吗

我尝试在fixtures加载闭包中手动设置baz:null,但仍然得到相同的结果。另一方面,当我只设置属性(比如一个简单的字符串)时,一切正常。只有当我开始建立关系的时候

这是Grails2.2.4、Fixtures 1.2的版本,并且没有安装构建测试数据插件

编辑:我有一些约束条件指定Baz为空且唯一。只是为了好玩,我也尝试添加
空白
约束,但没有成功

static constraints = {
    baz nullable:true, unique: true, blank: true
}
编辑2:以下是代码的简化版本:

class Foo {
    String someValue1
    String someValue2
    String whatever
    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 = {
        //there are no constraints for Bar
        baz nullable:true, unique:true
    }
}

class Bar {
     String someOtherValue
     static hasMany = [foos:Foo]
     static mapping = { 
        id generator:'assigned', name:'someOtherValue'
     }
}

class Baz {
    String someValue1
    String someValue2
    String asdf

    static mapping = {
        id composite: ['some_value_1', 'some_value_2']
        version false
    }
}

class MyTest {
    def fixtureLoader
    @Before
    void setup() {
        fixureLoader.load {
            myBar(Bar, someOtherValue:"shibby")
            myFoo(Foo, someValue1:"test", someValue2:"test2", bar:myBar)
            //i also tried this
            //myFoo(Foo, someValue1:"test", someValue2:"test2", bar:myBar, baz:null)
        }
    }
}
以下是部分例外情况:

原因:org.h2.jdbc.jdbccbatchUpdateException:引用完整性 约束冲突:“FK190E74B120F4F2BC:MYSCHEMA.FOO-FOREIGN 键(一些值1,一些值2)引用MYSCHEMA.BAZ(一些值1, 一些“值(2)”;SQL语句:插入MYSCHEMA.foo(无论什么, 一些其他值,一些值,一些值,一些值?, ?,?,?)[23506-164]


编辑:对不起,我刚才说错了。Bar与Foo有多对一的关系。

您的简化版代码(除了在Bar中有许多
)对我有效,没有任何FK例外。尽管我更喜欢使用不同的方法来实现真正的一对一双向关系,但前提是我正确地使用父映射和子映射

下面是我的设置,它在没有FK约束异常的情况下运行良好。请注意,我在评论中也提到,假设Foo有一个Bar和一个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)
注释

  • 上面我使用了您的精确简化代码,但是
    在Bar中有许多关系
  • Baz
    上的约束是可选的
  • 设备按预期工作
  • 按预期在Foo中创建列
  • logSql
    显示了预期的DML
  • 为了见证表的更改,我还在开发模式下启动了相同的测试数据,然后运行了一个
    runapp
    。使用
    dbconsole
    ,我能够看到包含数据的预期表结构
  • 按照一对一双向的一般方式(称为注释代码),FK是在子表[
    Bar
    Baz
    ]中创建的,因此示例代码中提供的显式映射不适用
  • 如果提到关系的拥有方以及在酒吧中拥有
    的理由,问题就会更加清楚
    
您的简化版代码(除了
中有许多
)适用于我,没有任何FK例外。尽管我更喜欢使用不同的方法来实现真正的一对一双向关系,但前提是我正确地使用父映射和子映射

下面是我的设置,它在没有FK约束异常的情况下运行良好。请注意,我在评论中也提到,假设Foo有一个Bar和一个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)
注释

  • 上面我使用了您的精确简化代码,但是
    在Bar中有许多关系
  • Baz
    上的约束是可选的
  • 设备按预期工作
  • 按预期在Foo中创建列
  • logSql
    显示了预期的DML
  • 为了见证表的更改,我还在开发模式下启动了相同的测试数据,然后运行了一个
    runapp
    。使用
    dbconsole
    ,我能够看到包含数据的预期表结构
  • 按照一对一双向的一般方式(称为注释代码),FK是在子表[
    Bar
    Baz
    ]中创建的,因此示例代码中提供的显式映射不适用
  • 如果提到关系的拥有方以及在酒吧中拥有
    的理由,问题就会更加清楚
    
你能举一个简单的失败例子吗?域类和装置会有帮助好的,我刚刚发布了它。您将条形图上的ID设置为
生成器:'assigned'
,但我看不到在任何地方设置ID值。这是否会导致Bar无法保存,而当你去保存Foo时,会导致引用完整性约束?myBar(Bar,someOtherValue:“shibby”)是不是没有设置id?在Bar w.r.t双向一对一关系中,
有许多
在做什么?你能举一个简单的失败例子吗?域类和装置会有帮助好的,我刚刚发布了它。您将条形图上的ID设置为
生成器:'assigned'
,但我看不到在任何地方设置ID值。这是否会导致Bar无法保存,而当您转到save Foo?myBar(Bar,someOtherValue:“shibby”)时,会导致引用完整性约束这不是设置id吗?
在Bar w.r.t中有许多
在做什么是双向一对一关系?我通过将Foo和Baz之间的关系更改为您建议的真正一对一关系来解决这个问题。也就是说,Foo上的静态hasOne=[baz:baz],以及baz中的Foo字段。谢谢你的实际尝试;有时候需要有人说“这对我有用”:@AlexBeardsley很高兴这对我有帮助。我按照你的建议,将Foo和Baz之间的关系改为真正的一对一关系,从而解决了这个问题。也就是说,Foo上的静态hasOne=[baz:baz],以及baz中的Foo字段。谢谢你的实际尝试;有时需要一个人