2013-05-11 109 views
1

我有一个给定的postgres db使用枚举类型的值为“M”,“F”。该值可以为null。当我尝试保存一个domainobject时,我收到下面的错误。Grails如何将枚举映射到数据库上的现有枚举

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}')" 

我的问题仍然是一样的:如何正确投字符串上插入?也'空'值尚未被接受。 谢谢!

回答

1

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

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

它想要插入一个字符串。它看起来像你的项目中的类和数据库之间的冲突。尝试从数据库中删除genderList类型。
从我的expirience我这样定义的:

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 
+0

不幸删除数据存储中的枚举是不是一种选择。 – 2013-05-12 22:11:12

+0

尝试添加value()和byValue()方法,可能是将字符串强制转换为枚举的问题。所以尽量按照描述使用。 – 2013-05-12 23:01:58

+0

@DominikH只要删除sqltype“genderlist”。您没有此类型,并且数据库值以字符串形式存储。 – 2013-05-16 15:53:51

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() 

无论如何,这将是更聪明的没有这个解决方法,因为查询必须随着域的每一个变化而改变。

0

使用你的Groovy性别枚举在UserLog域类和设置列的sqlType在映射的用户日志:

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

结果在相同类型错配枚举(数据库)<->字符变化(表达式)。但至少我可以保存具有空值的性别。我试过了:'UserLog u = new UserLog(gender:“M”)''UserLog u = new UserLog();保存前u.gender = GenderCode.fromValue(“M”)。 – 2013-05-17 00:13:53