Query domain class associations in Grails - grails

I have a few domain classes similar to the following:
class Position {
String code
String title
static hasMany = [relations: Relation]
}
class Unit {
String code
String title
static hasMany = [relations: Relation]
}
class Relation {
Position position
Unit unit
static belongsTo = [
position: Position,
unit: Unit
]
}
I am attempting to use criteria to find all positions that do not have any relations. I know this can be solved using HQL but I find the criteria to be cleaner when building dynamic criteria versus building a dynamic HQL string.
Is there a way to use criteria to do something like:
Position.withCriteria { isNull('relations') }
I have tried the above but I always get a list containing 0 elements even though I know there are unrelated positions in the table.

For collections you need to use isEmpty() instead of isNull().
Position.withCriteria { isEmpty('relations') }

Related

How to apply index in descending order in grails domain class?

I have written a domain class
class ReportCallByUser {
Integer userId;
String userName;
String reportName;
Date timeOfReportCall;
static constraints = {
}
static mapping = {
timeOfReportCall index: 'time_of_report_call_index'
}
The last line creates an index in database but in ascending order. How can I create index on 'timeOfReportCall' with descending order?
Thanks in advance.
There's no such thing as order in regards to index creation. It's the query's ability to specify the ordering:
ReportCallByUser.list( [ sort:'timeOfReportCall', order:'[desc|asc]' ] )
I am assuming that you want the results in descending order by default when you query the database using GORM. If that is the case, you can specify sort order in your mapping as such.
static mapping = {
sort timeOfReportCall:"desc"
}
Hope that helps.

Grails/Gorm : Sorting hasMany relationship

I have a domain class that has a 'hasMany' relationship that I would like to sort on so results are consistent when retrieving. Below is an example of the domain class.
class Author {
static hasMany = [ books: Book ]
static mapping = {
books sort: 'title', order: 'asc'
}
}
This produces the following error.
Default sort for associations [Author->books] are not supported with
unidirectional one to many relationships.
How can I sort on title in this example?
I have been able to achieve sorting on another hasMany relationship. Any feedback would be most appreciated.
As the error suggests you need to make the relationship bidirectional for default order to work,
just add the following in Book domain
static belongsTo = [author:Author] if you need default sort order to work.
Check if it will work for you
class Author {
SortedSet books // add this to your Author domain
static hasMany = [books: Book]
}
class Book implements Comparable {
String title
int compareTo(obj) {
title.compareTo(obj.title)
}
}

Grails querying model containing an enum set

My domain class is
class RoomWantedAd{
Set<MateAgeRange> mateAgeRanges
static hasMany=[mateAgeRanges :MateAgeRange]
}
Her MateAgeRange is :
enum MateAgeRange {
TWENTIES('18-29')
,THIRTIES('30-39')
,FOURTIES("40-49")
,FIFTIES("50-59")
,SIXTIES("60+")
final String value
private MateAgeRange(String value) {
this.value = value
}
String toString() { value }
String getKey() { name() }
static belongsTo=[roomWanted:RoomWanted]
}
My problem is searching. In the search page, a person can select 0 or more values in [18-29, 30-39, 40-49, 50-59, 60+]. In the db, 0 or more values among [18-29, 30-39, 40-49, 50-59, 60+] are stored in field 'mateAgeRanges'.
Let db contains [30-39, 50-59] in 'mateAgeRange' field. Let in the search page, the user selects [18-29, 50-59, 60+]. Then the Ad corresponding to the above list must be returned. This is because at least one value in user's selection is present in the db list. How is it possible. Is it possible using an SQL query or grails GORM query.
you have to use exactly the same <g:select/> tag as you are using for create/update. Thus, you will see human readable values like THIRTIES in browser, but in the background the '30-39' values will be used.

Grails change database column size of a hasMany of Strings

I have a domain class that looks like the following:
class Foo {
static hasMany = [bar: String]
}
The problem is that this creates a join table with a column of VARCHAR(255) in MySQL, which much larger than I need it to be. In my example, bar is a Set not an indexed collection, so trying to use indexColumn does not work. joinTable does not have an attribute to change the column type/length. Is it possible to change to column size without changing the structure of the domain class?
This works (tested with grails 2.4):
class Foo {
static hasMany = [
bars:String
]
static mapping = {
bars joinTable: [column: 'BARS_STRING', length: 112]
}
}
You can also try sqlType, like
class Foo {
static hasMany = [bar: String]
static mapping = {
names joinTable: [column: 'bar', sqlType: 'varchar(32)']
}
}

Does findAllBy return a sorted list?

Does findAllBy return a sorted list? I could not find any information in the Grails documentation about this. Assuming I have a class like so:
class Something {
int sortOrder
String label
static belongsTo = [ somethingElse: SomethingElse]
static mappedBy = [somethingElse: SomethingElse]
static mapping = {
tablePerHierarchy false
sort "sortOrder"
}
static constraints = {
}
}
Does Something.findAllBySomethingElse(somethingElse) return a list that is sorted by "sortOrder"? It's strange but my unit tests says no whereas my grails app (when i do run-app) displays the list in sorted order. I had to explicitly use findAllBySomethingElse(somethingElse, [sort: "sortOrder"]) to enable my unit tests (i.e. checking sort order) to pass.
It does return a sorted list. But not in Unit Tests. They are not intended for such things, but can be extended to some degree. See the unit test documentation.

Resources