When working with Grails domain models I often find myself wondering: How is this modeled in the database?
The combinations of
belongsTo, (and the occasional
hasOne) lead to the one-to-many, many-to-many, many-to-one, and one-to-one associations. But how? What are these combinations? Well, feast your eyes on some Groovy and relational database porn.
In the first example, an
Author has many
Books, producing a one-to-many uni-directional relationship. Uni-directional meaning that an
Author has a reference to its
Books, however, a
Book has no clue about its
Author. The association is created with the
hasMany static property in the
Author domain class.
1 2 3 4 5 6 7 8 9 10 11
As shown in the database diagram, Grails creates a join table to represent the one-to-many association. The join table has two foreign key columns: the
Author's ID, and the
It's worth nothing, since the
Book does not have a reference to its
Author, it's possible for multiple
Authors to have the same
Book. Notice how the
author_book table makes this possible. To have Grails enforce that you want a
Book to have a single
Author, you'll need a bi-directional one-to-many association.
With a bi-directional association, a
Book is given a property which references its
Author. This is done by adding a
belongsTo static property to the
1 2 3 4 5 6 7 8 9 10 11 12 13
Now, a foreign key is added to the
Book containing the
Author's ID. The join table is simply not used anymore. This implies that without an
Author there can be no
Book. Put differently, an
Author owns its
A many-to-many association is created by using a
hasMany static property in both domain classes. And, by using a
belongsTo static property lacking a back-reference in the
Book domain class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Like a uni-directional one-to-many, a many-to-many association uses a join table. In fact, at the database level it looks identical to a uni-directional one-to-many.
Creating a uni-directional many-to-one association doesn't require
hasMany or the like. It's just a matter of adding an instance property.
1 2 3 4 5 6 7 8 9 10
A bi-directional many-to-one is created using the static
belongsTo property. Surprisingly, this doesn't affect the database.
1 2 3 4 5 6 7 8 9 10 11 12
Finally, you get to see the static
hasOne property in action!
1 2 3 4 5 6 7 8 9 10
In the database, it looks just like a bi-directional one-to-many.
As you've just read, it takes a precise combination of the
hasOne static properties, and sometimes an instance property, to assemble the various Grails domain class associations. Some are self-explanatory, others not so much. Either way, you may reference this guide when you need it.