1

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

postgres 枚举:

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 被正确地转换为字符串表示。尝试插入数据时,转换仍然是一个问题。

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

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

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

我的问题仍然是一样的:我如何在插入时正确地转换字符串?'null' 值也不被接受。谢谢!

4

3 回答 3

0

在 grails 中,您的自定义枚举存储为字符串。看看日志

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

它想插入一个字符串。看起来项目中的类与数据库之间存在冲突。尝试从数据库中删除性别列表类型。
根据我的经验,我这样定义:

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
于 2013-05-11T20:50:56.037 回答
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()

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

于 2013-05-16T21:26:55.640 回答
0

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

class UserLog {
    GenderCode gender = null
    ...
    static mapping = {
        gender sqlType: 'enum'
    }
}
于 2013-05-16T21:51:53.157 回答