Grails 2.3.2:在Bootstrap中使用Enums的findOrCreate

时间:2013-11-17 13:30:59

标签: mysql grails enums gorm

我在使用Bootstrap.groovy中的findOrCreateBy方法时遇到了麻烦。

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 }
}

在Bootstrap中,我尝试创建Guest,如果它们还不存在的话。

Guest guest = Guest.findOrCreateByFirstnameAndLastnameAndGender(firstname, lastname, Gender.MALE)
guest.save()

我第一次针对MySQL运行应用程序一切正常。应用程序启动没有任何错误。如果我第二次运行应用程序(这次是数据库中的guest虚拟机),我会遇到以下故障。

| 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

这似乎是Gorm第一次将值'0'和'1'写入数据库。在第二次运行中,它无法将这些0和1转换为相应的枚举值。谁能告诉我我做错了什么?

3 个答案:

答案 0 :(得分:1)

尝试此操作 - 将参数generateSimpleParameterMetadata=true添加到您的网址连接字符串

...
url = "jdbc:mysql://localhost/bootstraptest?generateSimpleParameterMetadata=true"
...

这与驱动程序解释枚举元数据的方式有关(坦白说我不太了解)请参阅http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html

此解决方案非常特定于数据库,因此您不需要任何其他更改

请注意,实际的枚举标签现在将存储在数据库中('NEW','WIP','DONE'而不是0,1,2)

答案 1 :(得分:0)

我认为这与mysql有关,我没有mysql来测试它并且从未使用过mysql,但是尝试专门映射枚举,如下所示:

static mapping = {
    ...
    gender column: 'gender', sqlType: 'enum', name: 'gender'
}

ref

如果您手动创建数据库表,请尝试为您的列创建类似于以下内容的枚举:

CREATE TABLE sizes (
    name ENUM('small', 'medium', 'large')
);

ref

这是另一篇可以帮助here

的文章

答案 2 :(得分:0)

我建议使用IdentityEnumType更改映射:

static mapping = {
    ...
    gender column: 'gender', type: IdentityEnumType
}

修改您的枚举,向其添加 id

public enum Gender {

MALE   (1, "male"),
FEMALE (2, "female"),

final Integer id
final String value

Gender (Integer id, String value) {
    this.id = id
    this.value = value
}

String getValue() {
    return value
}

String toString() {
    return name()
}

String getKey() {
    return name()
}

那应该对你有帮助。