Mysql Grails2.3.2:findOrCreate在引导中使用枚举
我在Bootstrap.groovy中使用findOrCreateBy方法时遇到问题Mysql Grails2.3.2:findOrCreate在引导中使用枚举,mysql,grails,enums,gorm,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 }
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.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转换为相应的枚举值。有人能告诉我我做错了什么吗?我认为这与mysql有关,我没有mysql来测试它,也从未使用过mysql,但请尝试专门映射枚举,如下所示:
static mapping = {
...
gender column: 'gender', sqlType: 'enum', name: 'gender'
}
如果要手动创建数据库表,请尝试为列创建枚举,如下所示:
CREATE TABLE sizes (
name ENUM('small', 'medium', 'large')
);
这是另一篇有帮助的文章我建议使用
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()
}
这应该会对您有所帮助。尝试此操作-将参数
generateSimpleParameterMetadata=true
添加到url连接字符串中
...
url = "jdbc:mysql://localhost/bootstraptest?generateSimpleParameterMetadata=true"
...
这与驱动程序解释枚举元数据的方式有关(坦率地说,我不太理解),请参见
此解决方案非常特定于数据库,因此不需要任何其他更改
请注意,实际的枚举标签现在将存储在数据库中(“新建”、“WIP”、“完成”而不是0、1、2)我创建了此场景,但无法重新创建错误。您确定错误不是来自其他操作吗?感谢您的快速响应。我需要保持数据库独立,以便在H2上运行测试,或者将来使用不同的DBMS部署。因此,使用特定于数据库的数据类型不是一个选项。有没有其他解决方法?对我来说,这东西就像一只虫子。我很确定我可以用H2文件数据库复制它。是的,这里也一样。嗯。这可能是Hibernate方言的问题吗?很好。它似乎非常具体。我明天会测试它,然后会给你一个很好的答案。我一直在寻找这样的解决办法。谢谢你帮了大忙!