1

У меня есть объект Foo, который имеет двунаправленную связь один-к-одному с баром, а другой - с Baz. Когда я пытаюсь сделать .load с помощью Foo и давать только Bar, я получаю исключения ссылочной целостности, жалующиеся на отсутствие Baz.Исправления для плагинов Исходные ссылочные исключения целостности в Grails

Должно ли это быть так? В реальной среде не возможно, что в базе данных не было бы соответствующего объекта Baz?

Я попытался вручную установить baz: null в закрытии загрузки светильников, но я все равно получаю то же самое. На стороне примечания, когда я только устанавливаю свойства (например, простую строку), все работает нормально. Только когда я начинаю устанавливать отношения.

Это с Grails 2.2.4, Fixtures 1.2 и без установленного плагина build-test-data.

EDIT: У меня есть ограничения, указывающие, что Baz является нулевым и уникальным. Просто для хихиканья я попробовал добавить ограничение blank, но не повезло.

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. JdbcBatchUpdateException: ссылочная целостность нарушение ограничений: «FK190E74B120F4F2BC: MYSCHEMA.FOO FOREIGN KEY (SOME_VALUE_1, SOME_VALUE_2) ССЫЛКИ МОЙ SCHEMA.BAZ (SOME_VALUE_1, SOME_VALUE_2) "; SQL заявление: (?????,,,,, ,) вставить в MYSCHEMA.foo (независимо от того, some_other_value, some_value_2, some_value_1) значения [23506-164]

EDIT: Извините, я опечалился раньше. Бар имеет много-к-одному отношения с Foo.

+0

Можете ли вы опубликовать простой пример неудачи? Доменные классы и светильники помогут –

+0

Хорошо, я только что разместил его. –

+0

У вас есть ID-строка, установленная на 'generator: 'assign'', но я не вижу, чтобы значение id было задано где угодно. Является ли это причиной того, что Bar не удалось сохранить, что затем приведет к ограничению ссылочной целостности при переходе к сохранению Foo? – proflux

ответ

1

Ваша упрощенная версия кода (кроме hasMany in Bar) работает для меня без исключения FK. Хотя я бы предпочел другой подход к достижению истинного одностороннего двунаправленного отношения, если я прав с родительским и дочерним отображением.

Ниже приведена моя настройка, которая отлично работает без исключения ограничений FK. Обратите внимание, что я также упомянул в комментариях, как бы я смог достичь истинного взаимно однозначного двунаправленного значения, принимающего . Foo имеет один бар и имеет один 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) 

Примечание

  • Выше я использовал свой точный упрощенный код, но и hasMany отношения в баре.
  • Ограничения на Baz не является обязательным.
  • Светильники работают должным образом.
  • Столбцы создаются в Foo, как ожидалось.
  • logSql показал ожидаемый DML.
  • Чтобы увидеть изменения таблицы, я также загрузил те же тестовые данные в режиме dev после run-app. Мне удалось увидеть ожидаемую структуру таблицы с данными в ней, используя dbconsole.
  • Следуя общему способу взаимно однозначного двунаправленного (упоминается как прокомментированный код), FK создаются в дочерних таблицах [Bar и Baz], поэтому явное сопоставление, которое вы предоставили в примере кода, не будет хорошо.
  • Вопрос будет более понятным, если упомянуть об отношении владельца и обосновании наличия hasMany в баре.
+0

Я исправил это, изменив отношения между Foo и Baz до истинного отношения «один к одному», как вы предложили. То есть, static hasOne = [baz: Baz] на Foo и поле Foo в Baz. Спасибо, что на самом деле попробовали это; иногда требуется, чтобы кто-то сказал «это работает для меня» :) –

+0

@AlexBeardsley Рад, что это было полезно. – dmahapatro