2013-05-11 134 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