I am having troubles with using the findOrCreateBy method in the Bootstrap.groovy.
class Guest {
String firstname
String lastname
Gender gender
static constraints = {
firstname blank: false
lastname blank: false
gender nullable: false
}
}
enum Gender {
MALE('male'), FEMALE('female')
final String v
Gender(String s) { v = s }
}
And in the Bootstrap I try to create Guests if they do not exist yet.
Guest guest = Guest.findOrCreateByFirstnameAndLastnameAndGender(firstname, lastname, Gender.MALE)
guest.save()
The first time I run the app against MySQL everything works fine. The apps starts without any error. If I run the app a second time (this time with guest in the database) I get the following failure.
| Error 2013-11-17 14:27:37,621 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Unknown name value [1] for enum class [ch.silviowangler.ch.cisposiamo.Gender]
Message: Unknown name value [1] for enum class [ch.silviowangler.ch.cisposiamo.Gender]
Line | Method
->> 105 | methodMissing in org.grails.datastore.gorm.GormStaticApi
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 106 | createGuest in BootStrap
| 102 | createGuest . . . . . . . . . . in ''
| 66 | doCall in BootStrap$_closure1
| 308 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 301 | executeForEnvironment in ''
| 277 | executeForCurrentEnvironment . . in ''
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . . . . . . . . . . . . in java.lang.Thread
It seems the the first time Gorm writes values '0' and '1' to the database. In the second run it fails to convert these 0 and 1 into the corresponding enum value. Can anybody tell me what I am doing wrong?
Try this - Add the parameter generateSimpleParameterMetadata=true
to your url connect string,
...
url = "jdbc:mysql://localhost/bootstraptest?generateSimpleParameterMetadata=true"
...
This has something to do with the way the driver interprets the enum meta data (frankly i don't understand it well) see http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html
This solution is very db specific, so you don't need any other changes
Note that the actual enum label will now be stored in the database ('NEW', 'WIP', 'DONE' instead of 0, 1, 2)