Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails Enum Mapping

in Grails, Is there a way to limit the size of the column to which the enum is mapped. In the following example, i would like the column type to be char(2)

enum FooStatus {
    BAR('br'), TAR('tr')
    final static String id
}

class Foo {
    FooStatus status

    static constraints = {
        status(inList:FooStatus.values()*.id,size:2..2)
    }
}

both inList and size do not have any effect when exporting the schema, the column type keeps its default value (varch(255)) Maybe i could do that if i define a new UserType. Any idea ?

Thank you -ken

like image 927
ken Avatar asked Sep 20 '10 04:09

ken


3 Answers

I don't think it's directly possible given the way enums are mapped internally in GORM. But changing the code to this works:

enum FooStatus {
   BAR('br'),
   TAR('tr')
   private FooStatus(String id) { this.id = id }
   final String id

   static FooStatus byId(String id) {
      values().find { it.id == id }
   }
}

and

class Foo {
   String status

   FooStatus getFooStatus() { status ? FooStatus.byId(status) : null }
   void setFooStatus(FooStatus fooStatus) { status = fooStatus.id }

   static transients = ['fooStatus']

   static constraints = {
      status inList: FooStatus.values()*.id
   }

   static mapping = {
      status sqlType: 'char(2)'
   }
}

Adding the transient getter and setter allows you to set or get either the String (id) or enum value.

like image 98
Burt Beckwith Avatar answered Nov 02 '22 06:11

Burt Beckwith


Grails ships with an undocumented (as far as I can tell anyway) custom Hibernate mapping for enums. The class is org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType. It won't let you set the column size but does make it easy to change what is stored in the DB for each enum value without having to add transient fields to your model.

import org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType

class MyDomainClass {
    Status status

    static mapping = {
        status(type: IdentityEnumType)
    }

    enum Status {
        FOO("F"), BAR("B")
        String id
        Status(String id) { this.id = id }
    }
}

You can run an 'alter table' in Bootstrap.groovy to shrink the column:

DataSource dataSource
...
Sql sql = new Sql(dataSource)
sql.execute("alter table my_domain_class change column status status varchar(1) not null")
like image 25
David Tinker Avatar answered Nov 02 '22 05:11

David Tinker


Even easier (works at least in Grails 2.1.0+)

class DomainClass {
    Status status
    static mapping = {
         status(enumType: "string")
    }
}

enum Status {
    OPEN     ("OPEN"),
    CLOSED   ("CLOSED"),
    ...

    String name
    Status (String name) {
        this.name = name
    }
}
like image 28
Alex Abdugafarov Avatar answered Nov 02 '22 05:11

Alex Abdugafarov