1

Bar와 양방향 일대일 관계가 있고 Baz와는 양방향 일대일 관계가있는 객체 Foo가 있습니다. Foo로 .load를 수행하려고 할 때 Bar에게만 줄 것을 요청하면 Baz가 없다는 불평하는 참조 무결성 예외가 발생합니다.Fixtures Plugin 참조 무결성 예외 Grails에서

이 경우가 좋을까요? 실제 환경에서는 데이터베이스에 일치하는 Baz 객체가 없을 가능성이 있습니까?

필자는 fixtures로드 클로저에서 수동으로 baz : null 설정을 시도했지만 여전히 동일한 결과를 얻습니다. 부가 메모에서 속성 (예 : 간단한 문자열) 만 설정하면 모든 것이 올바르게 작동합니다. 그것은 내가 관계를 설정하기 시작할 때뿐입니다.

이것은 Grails 2.2.4, Fixtures 1.2 및 build-test-data plugin이 설치되어 있지 않은 것입니다.

EDIT : Baz를 null 허용 및 고유하게 지정하는 제약이 있습니다. 단지 킥킥 웃음을 위해서 나는 blank 제약 조건을 추가하려했지만 행운은 없었다.

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

EDIT 2는 : org.h2.jdbc :

의해 발생 :

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) 
     } 
    } 
} 

여기 예외의 일부이다 : 다음 코드의 간략화 된 버전이다. JdbcBatchUpdateException : 참조 무결성 제약 조건 위반 : "FK190E74B120F4F2BC : MYSCHEMA.FOO 외래 KEY (SOME_VALUE_1, SOME_VALUE_2) 참조 SCHEMA.BAZ (SOME_VALUE_1, SOME_VALUE_2) "; SQL 문 : (????????,,,,, ,,) (무엇이든, some_other_value, some_value_2, some_value_1) 값 MYSCHEMA.foo에 삽입 [23506-164]

편집 : 죄송합니다. 일찍 발표하지 못했습니다. Bar는 Foo와 다 대일 관계를 맺고 있습니다.

+0

간단한 실패 사례를 게시 할 수 있습니까? 도메인 클래스 및 픽스쳐가 도움이 될 것입니다. –

+0

좋아, 방금 게시했습니다. –

+0

Bar에 ID가 'generator :'assigned''로 설정되어 있지만 ID 값이 어디에도 설정되어 있지 않습니다. Bar가 저장 실패로 인해 Foo를 저장할 때 참조 무결성 제약 조건을 유발합니까? – proflux

답변

1

간단한 코드 버전 (바에서 hasMany 제외) 은 나를 위해 FK 예외없이 작동합니다. 부모와 자식 매핑이 정확하다면 나는 진정한 one-one 쌍방향 관계를 성취하기 위해 다른 접근법을 선호 할지라도.

다음은 FK 제약 조건 예외없이 올바르게 작동하는 제 설정입니다. 덧붙여서 나는 또한 주석에서 1 대 1 양방향을 실현할 수있는 방법을 언급했다. Foo는 하나의 Bar를 가지고 있고 하나는 Baz을 가지고있다. 나는 정확한 간단한 코드 만 바에서 hasMany 관계를 사용한보다도

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) 

노트

  • .
  • Baz에 대한 제약 조건은 선택 사항입니다.
  • 예상대로 조명기가 작동합니다.
  • Foo에서 예상대로 열을 만듭니다.
  • logSql은 예상되는 DML을 나타내었다.
  • 테이블 변경 사항을 확인하기 위해 동일한 테스트 데이터를 run-app 다음의 dev 모드로 부트 스트랩했습니다. dbconsole을 사용하여 데이터가 포함 된 예상 테이블 구조를 볼 수있었습니다.
  • 일대일 양방향 (주석 코드로 언급)의 일반적인 방법에 따라 FK는 자식 테이블 [BarBaz]에 만들어 지므로 예제 코드에서 제공 한 명시 적 매핑이 좋지 않습니다.
  • Bar의 hasMany 뒤에있는 관계 및 소유주의 근거가 언급되는 경우 질문이 더 명확 해집니다.
+0

Foo와 Baz 사이의 관계를 제안한대로 일대일 관계로 변경하여이 문제를 해결했습니다. 즉, Foo에는 정적 hasOne = [baz : Baz]가 있고 Baz에는 Foo 필드가 있습니다. 이것을 실제로 시도해 주셔서 감사합니다. 때때로 그것은 "나를 위해 일한다"라고 말하는 사람이 필요합니다 :) –

+0

@AlexBeardsley 다행입니다. – dmahapatro