2014-09-03 4 views
0

У меня есть классы домена два:Grails Горм нулевых полей

class Person { 

    String lastname 
    String firstname 
    String alias 
    Date birthday 
    String notes 
    static belongsTo = [addressBook: AddressBook, mainAddress: Address] 
    static hasMany = [tags: Tag, addresses: Address] 

    static constraints = { 
     mainAddress nullable: true 
     addresses nullable: true 
     alias nullable: true 
     birthday: nullable: true 
     tags nullable: true 
     notes nullable: true 
    } 
} 

и

class Address { 

    AddressType addressType 

    static belongsTo = [person: Person] 
    String company 
    String street 
    String zipCode 
    String city 
    String eMail 
    String phone 
    String mobile 
    String website 

    static constraints = { 
     person nullable: true 
     company nullable: true 
     website nullable: true 
    } 
} 

Предполагается, что каждый человек имеет несколько адресов и может определить один адрес в качестве основного-адреса.

Внутри моего контроллера я делаю

params.max = Math.min(max ?: 10, 100) 
respond Person.list(params) 

для загрузки всех лиц, со всеми адресами. Получаемые объекты person содержат список адресов со всеми адресами и mainAddress. Но адреса, которые используются в качестве основного адреса, имеют только пустые (нулевые) поля в обоих объектах (один в списке и mainAddress-object.). Когда я не устанавливаю mainAddress, адрес-объект в списке адресов поставляется со всеми правильно настроенными полями. Поля базы данных (я использую в-памяти-дб до сих пор) кажутся правильными:

create table address (id bigint generated by default as identity, version bigint not null, address_type varchar(255) not null, city varchar(255) not null, company varchar(255), e_mail varchar(255) not null, mobile varchar(255) not null, person_id bigint, phone varchar(255) not null, street varchar(255) not null, website varchar(255), zip_code varchar(255) not null, primary key (id)) 
create table person (id bigint generated by default as identity, version bigint not null, address_book_id bigint not null, alias varchar(255), birthday timestamp not null, firstname varchar(255) not null, lastname varchar(255) not null, main_address_id bigint, notes varchar(255), primary key (id)) 

Кто-нибудь идея, почему мое отображение не работает?

Спасибо за помощь заранее

Roland

+0

класс принадлежит лицуТя адрес и адрес принадлежит лицу? вы, должно быть, шутите – injecteer

+0

, вероятно, вы имели в виду 'Person hasOne Address' и' Address принадлежит человеку'? – injecteer

ответ

1

Есть целый ряд вещей неправильно с вашей моделью, наиболее серьезным является то, что отношения людей-mainAddress не имеет владельца, то есть каждую сторона belongsTo других , Если это возможно, я бы упростить вашу модель для

class Person { 
    // non-address properties omitted, because they're not relevant to this question 
    static hasMany = [addresses: Address] 

    Address getMainAddress() { 
     Address.createCriteria().get { 
      eq 'person', this 
      eq 'isMain', true 
     } 
    } 

    static transients = ['mainAddress'] 

    static constraints = { 

     addresses nullable: true, validator: { addresses -> 

      // this prevents a person from having more than one main address 
      addresses?.count { it.isMain } <= 1 
     } 
    } 
} 

class Address { 
    // non-person properties omitted, because they're not relevant to this question  
    boolean isMain = false 

    static belongsTo = [person: Person] 

    static constraints = { 
     // is it really OK for an address not to be associated with a person? 
     person nullable: true 
    } 
} 

Я думаю, что это соответствует вашим требованиям, но является более простой моделью, потому что есть только один (один-ко-многим) отношения между Person и Address

+0

Спасибо за ваш ответ, который я тоже пробовал, и который отлично работает. Я предпочел решение, которое я разместил, потому что с флагом isMain мне пришлось бы поочередно перебирать список адресов каждый раз, когда я должен узнать mainAddress. – Roland

+0

@Roland не обязательно, я добавил метод getMainAddress() '' Person, который будет извлекать основной адрес (если он существует) без повторения по всем адресам –

+0

Предоставление геттера предлагает отличное решение, которое в пользу для моего решения не требуется дополнительная таблица соединений. Это также более гибко, потому что вы делаете запрос для mainAddress только в том случае, если это действительно необходимо. Большое спасибо. – Roland

1

Я теперь нашел решение:

class Person { 

    Address mainAddress 
    static hasMany = [addresses: Address] 

    static constraints = { 
     addresses nullable: true 
     mainAddress nullable: true, unique: true 
    } 

    static mapping = { 
     addresses joinTable: [name: 'person_address',key: 'person_id', column: 'address_id'] 
     mainAddress lazy: false 
    } 
} 

class Address { 
} 

Таким образом, адреса отображаются над нарисуйте таблицы person_address, в то время как mainAddress отображается через main_address_id в адресном столе. Требуется «mainAddress: lazy» -mapping, потому что в противном случае поля mainAddress не заполняются.

Смежные вопросы