1

Bar と双方向の 1 対 1 の関係を持つオブジェクト Foo と、Baz との別のオブジェクトがあります。Foo で .load を実行しようとして Bar のみを指定すると、Baz がないという不平を言う参照整合性の例外が発生します。

これは本当にそうであるべきですか?実際の環境では、データベース内に一致する Baz オブジェクトが存在しない可能性はありませんか?

フィクスチャのロード クロージャで baz:null を手動で設定しようとしましたが、それでも同じ結果が得られます。ちなみに、プロパティ (単純な文字列など) のみを設定すると、すべて正常に動作します。人間関係を築き始めたときだけです。

これは Grails 2.2.4、Fixtures 1.2 で、build-test-data プラグインがインストールされていない場合です。

EDIT : Baz が null 可能で一意であることを指定する制約があります。くすくす笑うために、blank制約も追加しようとしましたが、うまくいきませんでした。

static constraints = {
    baz nullable:true, unique: true, blank: true
}

EDIT 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.JdbcBatchUpdateException: 参照整合性制約違反: "FK190E74B120F4F2BC: MYSCHEMA.FOO FOREIGN KEY(SOME_VALUE_1, SOME_VALUE_2) REFERENCES MYSCHEMA.BAZ(SOME_VALUE_1, SOME_VALUE_2)"; SQL ステートメント: MYSCHEMA.foo (whatever, some_other_value, some_value_2, some_value_1) 値 (?, ?, ?, ?, ?, ?, ?, ?) に挿入します [23506-164]

編集:申し訳ありませんが、私は以前に言い間違えました。Bar は Foo と多対 1 の関係にあります。

4

1 に答える 1

1

コードの簡略化されたバージョン ( hasManyBar を除く)は、FK 例外なしで機能します。親と子のマッピングが正しければ、真の1対1の双方向関係を実現するために別のアプローチを好むでしょう。

以下は、FK 制約例外なしで正常に動作する私のセットアップです。Foo に Bar が 1 つと Baz が 1 つあると仮定して、真の 1 対 1 の双方向を実現する方法についてもコメントで言及したことに注意してください。

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)

ノート

  • 上記では、正確な単純化されたコードを使用しましたがhasMany、Bar の関係を使用しました。
  • Constraints onBazはオプションです。
  • 備品は期待どおりに機能します。
  • 列は予想どおり Foo に作成されます。
  • logSql予想される DML を示しました。
  • テーブルの変更を確認するために、run-app. を使用して、データを含む予想されるテーブル構造を確認できましたdbconsole
  • 1 対 1 の双方向の一般的な方法 (コメント付きのコードとして言及) に従って、子テーブル [BarおよびBaz] に FK が作成されるため、サンプル コードで指定した明示的なマッピングは適切に保持されません。
  • hasMany関係の所有側とバーでの所有の根拠が言及されている場合、質問はより明確になります。
于 2013-08-20T04:02:32.377 に答える