views:

622

answers:

2

Consider the following usages of the Grails/GORM dynamic finder method findAllBy*:

def foo1 = Foo.findAllByYear(yyyy)
def foo2 = Foo.findAllByMonth(mm)
def foo3 = Foo.findAllByDay(dd)
def foo4 = Foo.findAllByYearAndMonth(yyyy, mm)
def foo5 = Foo.findAllByYearAndDay(yyyy, dd)
def foo6 = Foo.findAllByYearAndMonthAndDay(yyyy, mm, dd)

println "# foo1=${foo1.size()} foo2=${foo2.size()} foo3=${foo3.size()}"
println "# foo4=${foo4.size()} foo5=${foo5.size()} foo6=${foo6.size()}"

The first five of these dynamic finder usages works as expected.

However, the sixth one fails with an InvalidPropertyException ("No property found for name [yearAndMonth] for class [class foo]").

Question:

Why doesn't the sixth one work? Isn't findAllBy* able to handle more than two conditions? Solution/work-around?

+4  A: 

Nope, not currently. It's limited to 2 conditions at the moment. For more than 2 look at the criteria builder or the findAllWhere methods.

Ted Naleid
+4  A: 

Ted's answer is correct, but the reason why Grails doesn't support more than 2 predicates is because if all the conjunctions are not the same then it's not clear what the intention is.

Or in plain English...

  • It's obvious what findAllByYearAndMonthAndDay(1999,2,3) means
  • It's also obvious what findAllByYearOrMonthOrDay(1999,2,3) means
  • But it's not obvious what findAllByYearOrMonthAndDay(1999,2,3) means

However, if all the conjunctions are the same (all ands or all ors), then there's no reason why more than 2 predicates couldn't be supported. In fact, if you search the Grails JIRA you'll find there's already an open issue for this. Vote for it if you feel strongly about it.

Incidentally, the IntelliJ Grails plugin erroneously provides code completion for dynamic finders with more than 2 predicates.

The solution/workaround is to simply write a Criteria query or use HQL instead.

Don