What is the best way to declare sorted association in grails domain classes?
Asked Answered
G

1

8

It seems that there are two different ways of declaring sorted associations in Grails :

Method 1 (see here) using default sort order

class Book {
  String title 
}
class Author {
  static hasMany = [books : Book]
  static mapping = { books sort: "title"}
}

Method 2 (see here) using SortedSet

class Book implements Comparable {
  String title
  int compareTo(obj) {
    title <=> obj.title
  }
}
class Author {
  SortedSet books
  static hasMany = [books : Book]
}

I am not sure which one to use and what is the difference (if any), pros and cons between using one against the other.

I would appreciate any clarification.

Thank you

Greenheart answered 15/5, 2010 at 13:57 Comment(1)
Find my answer if it is helpful for you: https://mcmap.net/q/1469924/-grails-testing-39-sort-39-mapping-in-a-domain-classLegalize
T
7

I started to dig into how this all works and then found that method 1 is actually busted in current versions of grails (tested in both 1.2.1 and 1.3). When you actually try to retrieve an author and look at it's books, it throws an exception

There is an open defect for it (4089) which has been open for quite a while.

Here's the exception that gets thrown:

ERROR util.JDBCExceptionReporter  - Column not found: BOOKS0_.TITLE in statement [select books0_.author_books_id as author1_0_, books0_.book_id as book2_0_ from author_book books0_ where books0_.author_books_id=? order by books0_.title]

If and when they finally fix it, the differences between the two methods are that in method one, sorting is done at the database level. As you can see in the exception above, GORM was trying to do an "order by books0_.title" which would use any database index on the book.title field and return the objects in that order.

The second method would sort the objects in memory at the time that they get inserted into the set (using the compareTo method that was defined).

Until the current bug is fixed, I'd use method 2 because it's the only thing that works. It should be fine for relatively small collections of things. After it's fixed, I'd potentially prefer method 1 as the database should be quicker at doing the sorting with an index on the sort field.

Terrarium answered 15/5, 2010 at 18:13 Comment(3)
Exactly what I needed ! Thank you! I am also using method 2 but when gone through Grails-1.2 Release Notes, I've discovered the method 1 and I was also supposing that the sorting was done at the DB level which is somewhat better than the SortedSet. I'll do like you : waiting for this bug to be fixed and switch once done. One question : in method 1, if declared as is, books is an instance os Set right?Greenheart
Yep, you'll have books as a Set. Set is the default for grails collections, they just aren't normally sorted (so they're a HashSet). If you wanted them to be a List, you'd have to declare it explicitly.Terrarium
Although the linked jira is marked as "Won't Fix", the workaround is to "make the relationship bidirectional with Book { ... static belongsTo = [author: Author] }."Mouthful

© 2022 - 2024 — McMap. All rights reserved.