4

I'm having trouble understanding the difference between declaring a domain-object in another domain and specifying the relationship between the domains.

Sample code:

class User { 
Book book
}

versus

class User { 
static hasOne = Book
}

class Book {
String name
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Daniel
  • 170
  • 2
  • 11

2 Answers2

3

The hasOne relationship will put the key on the child object, so in the db you'll find book.user_id with hasOne rather than user.book_id if you just declare Book book on User. You'll see the difference in the DDL generated if you use grails schema-export.

Here's the DDL with hasOne in place:

create table book (id bigint generated by default as identity (start with 1), version bigint not null, user_id bigint not null, primary key (id), unique (user_id));
create table user (id bigint generated by default as identity (start with 1), version bigint not null, primary key (id));
alter table book add constraint FK2E3AE98896CD4A foreign key (user_id) references user;

Here's the DDL with just Book book on User:

create table book (id bigint generated by default as identity (start with 1), version bigint not null, primary key (id));
create table user (id bigint generated by default as identity (start with 1), version bigint not null, book_id bigint not null, primary key (id));
alter table user add constraint FK36EBCB952E108A foreign key (book_id) references book;

Notice that the book table has the reference in the first example and the user has it in the 2nd.

Long answer: I strongly recommend watching Burt Beckwith's presentation on GORM/collections/mapping. Lots of great info around GORM and the consequences of various advantages/problems with describing relationships with hasMany/belongsTo, etc.

Ted Naleid
  • 26,511
  • 10
  • 70
  • 81
  • Hi Ted, Thanks so much for sharing the knowledge and the video! While doing research before asking the question (i even went to 5th page google results on multiple queries.) I actually came upon this video but quickly dismissed it. After watching just the first 15 min I feel I have learned so much stuff that I needed to know that wasn't covered in the books I have. I'm clearly new to grails but have a decent background on relational databases, this is my first time not actually coding the sql, so I was feeling very uneasy about efficiency. Thanks again! – Daniel Mar 13 '11 at 06:31
  • Nice one, thanks. Just an advice, keeping the order of examples in the answer (as asked in the question) would help the reading. :) – lucke84 Jun 30 '11 at 09:24
1

The main difference is that when using hasOne the foreign key reference is stored in the child table instead of the parent table, i.e. a user_id column would be stored in the book table instead of a book_id column being stored in the user table. If you didn't use hasOne, then a book_id column would be generated in the user table.

There is an explanation and example in the Grails documentation for hasOne.

Hope this helps.

Maricel
  • 2,089
  • 13
  • 17