Search code examples
grailsgrails-orm

grails gorm null fields


I have a two domain classes:

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

and

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

It is intended, that every person has multiple addresses and can define one address as main-address.

Inside my controller I do a

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

to load all persons with all addresses. The person-objects I receive contain a addresses-list with all addresses and the mainAddress. But the addresses that are used as main address have only empty (null) fields in both objects (the one in the list and the mainAddress-object.). When I dont set the mainAddress the address-object in the addresses-list comes with all fields properly set. The database fields (I use the in-memory-db so far) seem to be correct:

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

Has anyone an idea, why my mapping is not working?

Thanks for your help in advance

Roland


Solution

  • There are a number of things wrong with your model, the most serious is that the person-mainAddress relationship has no owner, i.e. each side belongsTo the other. If possible, I would simplify your model to

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

    I think this meets your requirements, but is a simpler model because there is only a single (one-to-many) relationship between Person and Address