简体   繁体   中英

Mapping the grails/groovy enum to Mysql enum

Here is my environment

Grails Version: 3.1.6
Groovy Version: 2.4.6
JVM Version: 1.8.0_51

The hibernate version in the build.gradle

compile "org.hibernate:hibernate-core:5.1.1.Final"
compile "org.hibernate:hibernate-ehcache:5.1.1.Final"

I expected to map the enum to MySql like this:

| Field       | Type                | Null | Key | Default | Extra         |
| logtype     | enum('DEBUG','INFO'| NO   |     | NULL    |                |

But I didn't get it work. I googled some suggestions but I didn't get them working.

this is my code:

 package xxxx

class Template {

    enum LogType {
        DEBUG("DEBUG"), INFO("INFO")
        String name
        LogType(name){
            this.name = name
        }
    }

    Integer tplID
    LogType lt

    static constraints = {
        tplID(nullable: true)
        lt(nullable: true)
    }


    static mapping = {
        table "Template"
        id name: "tplID"
        tplID column: "tplID", comment: "ID"
        lt sqlType: "enum", column: "lt", enumType: "DEBUG"
    }
}

I read the docs here http://docs.grails.org/3.1.1/ref/Database%20Mapping/column.html

And I am not sure the usage of enumType is correct, can anyone get it work?

Updated, the following code still doesn't work

class Template {

    enum LogType {
        DEBUG("DEBUG"), INFO("INFO")
        String name

        LogType(name) {
            this.name = name
        }
    }

    LogType lt

    static constraints = {
    }

    static mapping = {
        table "Template"
        lt sqlType: "enum", enumType: 'string'
    }
}

first for your question- you have it explained in docs:

enumType (optional) - The enum type in for type-safe Enum properties. Either ordinal or string. link

that means you can use either:

  • enumType: 'ordinal' which will store enum by using its ordinal number

Note: Ordinal number is position in its enum declaration, where the initial constant is assigned an ordinal of zero. link

  • or enumType: 'string' which will store enum with its enum name

...

To other problems I've noticed in your code:

  • You don't need to create your own name property for enum LogType , enums already has one, which is equal to declaration name.

  • You don't need to explicitly define table/column names if they are same as class/field names.

  • Your table uses nullable ID

EDIT:

so this is your edited code with my comments what can be improved/removed

class Template {

    //no need to define own name field, remove own implementation
    enum LogType {
        DEBUG("DEBUG"), INFO("INFO")
        String name 

        LogType(name) {
            this.name = name
        }
    }

    LogType lt

    static constraints = {
    }

    static mapping = {
        table "Template" //name can be infered from domain class name
        lt sqlType: "enum", enumType: 'string' 
        // sqlType is infered from variable
        // there is no 'enum' sql type (I think its inherited from hibernate)
        // enumType: 'string' is by default  
    }
}

existing hibernate types

and this can be your class with mentioned changes:

class Template {

    enum LogType {
        DEBUG, INFO
    }

    LogType lt
} 

EDIT2:

I do not recommend this, but you can configure underlaying sql type like this (not tested but should work):

static mapping = {
    lt sqlType: 'enum(DEBUG, INFO)'
}

Take note that your application will now support only MySQL databases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM