2017-02-14 15 views
0

в документах grails/gorms, в которой говорится, что вы можете поместить встроенный класс в тот же файл класса домена, что и класс родительского домена верхнего уровня - это работает с точки зрения кода, но по-прежнему генерирует таблицу GeoAddress, а также встраивает столбцы в исходную таблицу. тестовые данные вводятся в место проведения - таблица geoAddress остается пустой.grails v3.2.6/встроенный класс gorm в том же классе domain.groovy создает таблицу Dummy DB

документация подразумевает, что эта встроенная таблица не должна генерироваться. Я могу попытаться переместить GeoAddress в свой собственный файл src/groovy, поэтому его из папки grails-app/domain, но тогда я должен «помнить, что я сделал это». было бы намного «чище» хранить в том же файле, что и содержащий класс.

, кроме как продвинуть GeoAddress обратно в полный класс домена в своем собственном праве - как я могу сказать, что gorm не создает таблицу для него, когда его использование встроено?

мой venue.groovy в Grails-приложении/папка домена

class Venue { 

    String name 
    LocalDate dateCreated 
    LocalDate lastVisited 
    LocalDate lastUpdated 
    GeoAddress location 
    Collection posts 


    static hasMany = [posts:Post]   
    static embedded =['location'] 

    static constraints = { 
     lastVisited nullable:true 
     location nullable:true, unique:true 
     posts  nullable:true 
    } 
    static mapping = { 
     location cascade: "all-delete-orphan", lazy:false, unique:true 
     posts sorted: "desc", cascade:"save-update" 


    } 
} 


class GeoAddress { 

    String addressLine1 
    String addressLine2 
    String addressLine3 
    String town 
    String county 
    String country = "UK" 
    String postcode 

    //adds addTo/removeFrom methods to venue 
    static belongsTo = Venue 

    static constraints = { 
     addressLine1 nullable:true 
     addressLine2 nullable:true 
     addressLine3 nullable:true 
     town   nullable:true 
     county  nullable:true 
     country  nullable:true 
     postcode  nullable:true 
    } 
} 
+0

чудо, если вы пробовали это как абстрактный класс и будь, что будет работать и держать вещи то же самое попробуйте объявить его как «абстрактный класс GeoAddress» – Vahid

+0

, он, безусловно, не может быть абстрактным классом, так как мне нужно создать экземпляр его для добавления к конструктору места. вы не можете иметь новый (), поэтому я не думаю, что это работает. –

+0

Я не думаю, что вы найдете ответ, который вам нужен, если вы обеспокоены созданием таблиц dbCreate - нужно ли автоматически генерировать базу данных из модели домена - один из «создания-падения», create ',' update 'или' validate 'я предполагаю обновление или, возможно, даже проверять, чтобы не создавать, а затем запускать 'grails export-schema' и вручную создавать таблицы самостоятельно – Vahid

ответ

0

Grails таблица поколение баз по имени класса, попытайтесь поместить встроенный в коллекции, а не класс.

+0

, он не может быть коллекцией в качестве своего 1: 1 - место встречи имеет место. Так что не стоит –

0

Я, кажется, разместил проводки на то, что по сути является одной и той же проблемой - небрежно. см. также can't get cascade save nor delete on embedded class ref to work

Однако, чтобы повторить. наличие встроенного класса, сидящего ниже основного класса в папках grails-app/domain, не останавливает создание встроенного класса (как это подразумевается в документах).

поэтому Горм идет вперед и создает вам место и географическое расположение (мой пример здесь). однако использование не является тем, что я ожидал, и именно поэтому тест не удался.

Если вы добавите новый объект GeoLocation в качестве конструктора, укажите место проведения переходного экземпляра в таблице места размещения во встроенных столбцах местоположения в одной таблице. Если вы удалите место проведения, вся строка будет удалена из таблицы места.

однако, если вы сначала создадите GeoLoaction и сохраните(), то его фактически сохранили в таблице GeoLocation. затем добавив его в место проведения обновления столбцов таблиц места.

поэтому, когда тест выполняет GeoLocation.list()/get(), он находит строку в этой таблице, а не смотрит в встроенные столбцы места.

Невозможно найти хороший выход из этого. Единственный способ остановить геолокацию, идущую в БД, - это переместить выделение из папок домена и поместить в src/groovy. Но тогда ваша модель домена разделяется на два поддерева, и получение валидации gorm для запуска за пределами папки с доменами более затруднительно.

Я думаю, что мне просто нужно было использовать GeoLocation как полный класс домена, а не использовать встроенные - и принять стоимость соединения. По крайней мере так, модель/тесты работают так, как вы могли бы ожидать.

результат не уверен, что внедренный было мудрое решение моделирования и я бы рекомендовал не использовать, если лет на самом деле не имеют к

+0

'the join cost' против процесса, чтобы попытаться добиться аналогичного эффекта, но встраивание класса домена все еще не уверен, что вы считаете его стоимость, если вы ввели кеш, если вы использовали такие вещи, как' String getAddressLine1() {return location.addressLine1} 'в классе« Место проведения »для каждого объекта, к которому вы хотите получить быстрый доступ, - затем использовали карты hql для четкого захвата определенных элементов из места объединения места, чтобы выбрать новую карту (v.name, l.addessLine1) из Место размещения v присоединяется к местоположению l 'таким образом, затраты минимальны - поскольку я говорю, что эти типы объединений слишком распространены, а встроенный редкий сценарий – Vahid

+0

, возможно, подчеркнул неправильную проблему - я могу жить со стоимостью соединения. моя реальная проблема заключалась в том, что, прочитав документы, я понял бы, что второй класс (встроенный) в том же файле класса остановит генерацию таблицы, и тогда у меня не было бы этой проблемы location.save() перейдя в таблицу GeoLocation, но место в конструкторе места размещения будет правильно сохранено, как указано в таблице места проведения. Это было слишком запутанно и мешало сосредоточиться на приложении –

+0

, вместо этого вы тратите время на то, чтобы понять, что делает gorm внизу - у меня нет возражений против обучения, но это просто не работало, как я читал он и я потеряли время, пытаясь понять, почему. Поэтому старайтесь держать это как можно проще и избегать некоторых «более приятных» функций, где он действительно создает путаницу для разработчика –

0

ОК - я нашел способ использовать геолокации, как встроенные и остановить его создания таблицы.

Мне пришлось установить GeoLoction как статический внутренний класс в боковом месте. Когда вы это сделаете и запустите приложение, вы не получите дополнительную ложную таблицу домена в БД. Он должен быть статическим внутренним классом, так как GeoLocation имеет статическое объявление для ограничений.

Я не уверен, если это ошибка или что - но документация Grails неверен в предложении в разделе 5.2 - состав в GORM, который говорит

Если определить класс Address в отдельный файл Groovy в каталоге grails-app/domain, вы также получите таблицу адресов. Если вы не хотите, чтобы это произошло использовать способность Groovy, чтобы определить несколько классов для каждого файла и включают в себя класс Address ниже класса Person в Grails-приложение/домен/файл Person.groovy

модифицированный класс показано ниже. если вы хотите, чтобы создать один из них формата (для начальной загрузки/тестов) будет выглядеть как новый Venue.GeoLocation (...)

class Venue implements Serializable { 

    String name 
    LocalDate dateCreated 
    LocalDate lastVisited 
    LocalDate lastUpdated 
    GeoAddress location 
    Collection posts 

    //static hasOne = [location:GeoAddress] //, temp:TempLocation 
    static hasMany = [posts:Post]   //but doesn't really own thats with user 
    static embedded =['location'] 

    static constraints = { 
     lastVisited nullable:true 
     location nullable:true, unique:true 
     posts  nullable:true 
    } 
    static mapping = { 
     location cascade: "all-delete-orphan", lazy:false, unique:true //eager fetch strategy 
     posts sorted: "desc", cascade:"save-update" 

     //comment out for now 
     //posts joinTable: [name:"venue_posts", key:"venue_id", column:"posts", type:Post] 
    } 

    static class GeoAddress { 

     String addressLine1 
     String addressLine2 
     String addressLine3 
     String town 
     String county 
     String country = "UK" 
     String postcode 

     //adds addTo/removeFrom methods to venue 
     static belongsTo = Venue 

     static constraints = { 
      addressLine1 nullable:true 
      addressLine2 nullable:true 
      addressLine3 nullable:true 
      town   nullable:true 
      county  nullable:true 
      country  nullable:true 
      postcode  nullable:true, 
        matches: /^([gG][iI][rR] {0,}0[aA]{2})|([a-pr-uwyzA-PR-UWYZ](([0-9](([0-9]|[a-hjkstuwA-HJKSTUW])?)?)|([a-hk-yA-HK-Y][0-9]([0-9]|[abehmnprvwxyABEHMNPRVWXY])?)) ?[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2})$/ 
     } 
    } 
}