In our application we have several entities that need addresses. But we've chosen to model them in a many-to-many relationship.
Address looks like this
class Address {
// typical address properties
Set<Company> getCompanies() {
CompanyAddress.findAllByAddress(this).collect { it.company } as Set
}
static constraints = {
// typical constraints
}
}
And for each "parent" we provide a getter. You can see getCompanies() in the code above. If you're only every going to have 1 company per address, then simply have that getter return the 1 company instead of a Set. The inverse is true inside Company, we have a getAddresses().
Company Address, for example, looks like this...
class CompanyAddress implements Serializable{
Address address
Company company
boolean equals(other) {
if (this.is(other)){
return true
}
if (!(other instanceof CompanyAddress)) {
return false
}
other.address?.id == address?.id &&
other.company?.id == company?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (address) builder.append(address.id)
if (company) builder.append(company.id)
builder.toHashCode()
}
static CompanyAddress get(long companyId, long addressId) {
find 'from CompanyAddress where address.id=:addressId and company.id=:companyId',
[addressId: addressId, companyId: companyId]
}
static CompanyAddress create(Company company, Address address, boolean flush = false) {
new CompanyAddress(address: address, company: company).save(flush: flush, insert: true)
}
static boolean remove(Company company, Address address, boolean flush = false) {
CompanyAddress instance = CompanyAddress.findByAddressAndCompany(address, company)
instance ? instance.delete(flush: flush) : false
}
static void removeAll(Address address) {
executeUpdate 'DELETE FROM CompanyAddress WHERE address=:address', [address: address]
}
static void removeAll(Company company) {
executeUpdate 'DELETE FROM CompanyAddress WHERE company=:company', [company: company]
}
static mapping = {
id composite: ['address', 'company']
version false
}
}