I’m working through Smith and Ledbrook’s Grails in Action. The examples in the book were written against Grails 1.1 and Hibernate 1.1 (according to the downloaded source’s application.properties).
One of the examples is “hubbub.” I have Grails 2.0.3 on my machine. I created my own copy of the application with, “grails create-app hubbub,” created my domain classes and tests with Grails commands, and then typed in the source in the book. In other words, I’m not trying to run a source tree that was generated with Grails 1.1 in a Grails 2.0.3 environment. Grails 2.0.3 generated all the configurations and classes that aren’t unique to the example. I just typed in the small amount of source in the example that wasn’t generated by Grails in the first place.
Here’s my problem – one of the integration tests uses the save() method to persist objects. When I run the test, and it contains only one save(), it succeeds. If the test contains more than one save() method, though, all calls to save() after the first one fail with:
| Failure: testSaveAndUpdate(com.grailsinaction.UserIntegrationTests)
| groovy.lang.MissingMethodException: No signature of method:
com.grailsinaction.User.save() is applicable for argument
types: () values: []
Possible solutions: save(), save(boolean), save(java.util.Map), wait(),
any(), wait(long)
at
com.grailsinaction.UserIntegrationTests.testSaveAndUpdate
(UserIntegrationTests.groovy:46)
I have rearranged the calls to save(), and the first one always works, while subsequent calls always fail. I have commented out tests to run each call to save by itself, and every one can succeed by itself.
Here’s the class upon which I call the save() method:
package com.grailsinaction
class User {
String userId
String password
String homepage
Date dateCreated
static constraints = {
userId(size: 3..20, unique: true)
password(size: 6..8)
homepage(url: true, nullable: true)
}
Here’s the integration test that calls save() on User:
package com.grailsinaction
import grails.test.*
class UserIntegrationTests extends GrailsUnitTestCase {
void testFirstSaveEver() {
def user = new User(userId: 'joe', password: 'secret',
homepage: 'http://www.grailsinaction.com')
assertNotNull user.save()
assertNotNull user.id
def foundUser = User.get(user.id)
assertEquals 'joe', foundUser.userId
}
void testSaveAndUpdate() {
def user = new User(userId: 'joe', password: 'secret',
homepage: 'http://www.grailsinaction.com')
assertNotNull user.save()
def foundUser = User.get(user.id)
foundUser.password = 'sesame'
foundUser.save()
def editedUser = User.get(user.id)
assertEquals 'sesame', editedUser.password
}
}
This is the data configuration from my generated DataSource.groovy (all environments but test edited out for brevity’s sake):
dataSource {
pooled = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
development {
...
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE"
}
}
production {
dataSource {
...
}
}
}
}
Here’s the original from the book:
dataSource {
pooled = true
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
...
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
...
}
}
}
The big difference that jumps out is that the original driver is org.hsqldb.jdbcDriver, while the one Grails 2.0.3 uses is org.h2.Driver. The other main difference is that the original datasource url is jdbc:hsqldb:mem:testDb, while the new one is jdbc:h2:mem:testDb;MVCC=TRUE. Finally, the specified caching mechanisms differ quite a bit.
Could this be a configuration issue having to do something with the differences between h2 and hsqldb? If so, what’s the best place for me to go to understand what I need to do to get this working?
In grails 2, you’re not supposed to extend
GrailsUnitTestCasein an integration test, change it toGroovyTestCaseand you should get rid of the problem.This fails because
GrailsUnitTestCasethinks it’s a unit test that has to mock (and then tear down and remove) GORM methods from the domain objects. It doesn’t realize it’s got the real methods, not mocks.