Reputation: 558
Starting with a github repo that demonstrates how to use GORM outside of Grails, I am attempting to use dynamic finders so that I can look up a particular domain object by one of its properties. In this example, we have this person object in groovy as such:
package domain
import grails.gorm.annotation.Entity
import org.grails.datastore.gorm.GormEntity
@Entity
class Person implements GormEntity<Person> {
String firstName
String lastName
static mapping = {
firstName blank: false
lastName blank: false
}
}
Now lets say I want to look up a person by last name. I should be able to use the GORM-enhanced Person entity method findByLastName
. I'm able to compile the code that attempts this, but when I call it at runtime, the method is not found.
I added a test method to PersonSpec.groovy that looks like this:
@Rollback
def "person can be found by last name"() {
when:
def p = new Person(firstName: 'Scott', lastName: 'Ericsson')
p.save(flush: true)
def foundPerson = p.findByLastName('Ericsson')
then:
foundPerson.firstName == 'Scott'
}
I get this error when the test is run:
domain.PersonSpec > person can be found by last name FAILED
groovy.lang.MissingMethodException at PersonSpec.groovy:32
The test method above it creates and saves a person record successfully, so some aspects of GORM functionality are working. But dynamic finder functionality is not being properly applied at run time, even though the compiler thinks everything looks good.
My entire build.gradle is this:
apply plugin: 'groovy'
repositories {
jcenter()
}
dependencies {
compile "org.hibernate:hibernate-validator:5.3.4.Final"
compile "org.grails:grails-datastore-gorm-hibernate5:7.0.0.RELEASE"
runtime "com.h2database:h2:1.4.192"
runtime "org.apache.tomcat:tomcat-jdbc:8.5.0"
runtime "org.apache.tomcat.embed:tomcat-embed-logging-log4j:8.5.0"
runtime "org.slf4j:slf4j-api:1.7.10"
testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
}
Does anyone know what I am missing?
Upvotes: 0
Views: 256
Reputation: 558
So I've been struggling with this for a couple of days, and wouldn't you know as soon as I post the question I figure it out almost instantly. It's simple--I need to use findByLastName method statically on the Person object instead of a person instance. The code that works in PersonSpec looks like this now:
@Rollback
def "person can be found by last name"() {
when:
def p = new Person(firstName: 'Scott', lastName: 'Ericsson')
p.save(flush: true)
def foundPerson = Person.findByLastName('Ericsson')
then:
foundPerson.firstName == 'Scott'
}
Upvotes: 2