Grails如何将枚举映射到数据库上的现有枚举

时间:2013-05-11 13:37:15

标签: grails enums gorm

我有一个给定的 postgres 数据库使用枚举类型,其值为“M”,“F”。该值可以为null。当我尝试保存域对象时,我收到以下错误。

postgres enum:

CREATE TYPE genderlist AS ENUM ('M','F')

我的枚举:

public enum GenderCode {

    M,F

    private final String value

    private static list

    public String value() {
        return name()
    }

    public static GenderCode fromValue(String v) {
        return valueOf(v)
    }

}

域类:

class UserLog {

    String gender = null //default null
    ..
}

BootStrap.groovy中:

// reading - works fine now
def rows = UserLog.list()

// insert - does not work
UserLog u = new UserLog(gender:null)
u.save()

错误:

| Batch-Entry 0 insert into user_log (active, birthyear, country, gender, user_id, id) values ('1', NULL, NULL, NULL, NULL, 98304) was cancelled.  
| ERROR: column "gender" is of type genderlist but expression is of type character varying
  Note: You will need to rewrite or cast the expression.

修改
我更新了整个问题以匹配我项目的当前状态。因为我更新了枚举,所以我不再有阅读数据的问题。 PGObject被正确地转换为String表示。尝试插入数据时,转换仍然是一个问题。

我有一个肮脏的小解决方法,有效:

    def sql = new Sql(dataSource_log)
    def map = [gender:'M']

    sql.executeInsert "insert into user_log (gender) values ('${map.gender}')"

我的问题仍然保持不变:如何在插入时正确地强制转换字符串?也不接受“null”值。 谢谢!

3 个答案:

答案 0 :(得分:1)

在grails中,您的自定义枚举存储为String。看一下日志

('1', NULL, NULL, 'M', NULL, 98304)

它想要插入一个String。它看起来像项目中的类和数据库之间的冲突。尝试从数据库中删除genderList类型 从我的经验来看,我的定义如下:

public enum ActivityState {
    ACTIVE("active"),
    NOT_ACTIVE("not_active")

    private final String value

    public ActivityState(String value) {
        this.value = value
    }

    String toString(){
        value
    }

    public String value() {
        value
    }

    public static ActivityState byValue(String value){
        values().find { it.value == value }
    }
}

像这样使用:

ActivityState activityState

答案 1 :(得分:0)

好吧我会说我自己通过直接sql查询保存到域类中来修复它:

class UserLog{

    ...

    public saveIt(){
        def sql = new Sql(dataSource_log)

        sql.executeInsert """ 
            insert into user_log(gender,.. ) 
            values ('${this.gender}', .. ) 
            """

        sql.close()
    }
}

保存实例:

Dummy d = new Dummy()
d.gender = 'M'
d.saveIt()

无论如何,没有这种解决方法会更聪明,因为必须随着域上的每次更改而更改查询。

答案 2 :(得分:0)

UserLog域类中使用您的groovy性别枚举,并在UserLog的映射中设置列的sqlType

class UserLog {
    GenderCode gender = null
    ...
    static mapping = {
        gender sqlType: 'enum'
    }
}