Showing posts with label one-to-many. Show all posts
Showing posts with label one-to-many. Show all posts

21 March 2008

Two ways to model One-to-Many in GORM

There are two subtly different, but distinct ways to model a One-to-Many relationship in GORM, each with some rather interesting implications.

Method One:
   1:class Book{
2: String title
3: static belongsTo = Author
4:}
5:
6:class Author {
7: String name
8: static hasMany = [books: Book]
9:}

This method results in the schema:


Furthermore, the following applys:
  1. An additional "link" table (author_book) will be created in the database.
  2. A books property will be available on Author
  3. There is no direct way of querying the reverse of the relationship. i.e. no straightforward way to lookup an Author if you're holding a Book object.(See this post for a solution)

Method Two:
   1:class Book{
2: String title
3: static belongsTo = Author
4: Author author
5:}
6:
7:class Author {
8: String name
9: static hasMany = [books: Book]
10:}
Note: The addition of "author" property at line 4 above.

This method results in the schema:



Furthermore:
  1. An additional column called author_id will be created on the Book table in the database
  2. No "link" table will be created in the database
  3. It is possible to query both the forward and reverse relationship by refering to the Books.author and Author.books properties respectively
FIN.

20 March 2008

GORM Criteria Query for One-to-Many

In Grails, GORM has some very nice features, not the least of which are Dynamic Finders. It's quite easy to sometimes overlook a really powerful and elegant alternative to dynamic finders in the form of Criteria. In this article I will cover one specific case in which there exists no dynamic finder for a specific use case, but for which a simple, elegant Criteria will do.
Consider the following one-to-many relationship in which One Author has many Books.

   1:class Book{
2: String title
3: static belongsTo = Author
4:}
5:
6:class Author {
7: String name
8: static hasMany = [books: Book]
9:}
The problem: Assuming we are holding a Book object, how do we find the associated Author for that book ? Here's how:
   1:def book = Book.findByTitle('Definitive Guide to Grails')
2:
3:def criteria = Author.createCriteria()
4:
5:def author = criteria {
6: books{
7: eq('id',book.id)
8: }
9:}
The often overlooked "trick" to the above criteria, is the fact that we can use the "books" property on Author in our Criteria to match against (line 6 above).

References: