tags:

views:

102

answers:

1

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

+2  A: 

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.

Burt Beckwith
It's quite annoying that i have to add for every enum type a getter and a setter and also declare it as "transient". Burt, wouldn't a custom UserType be a more elegant solution ?
ken
The transient and getter/setter are optional if you're ok with setting the Enum's id and converting the id to the enum instance in the calling code. The real change is persisting a String instead of the Enum (which was sort of implied by your use of inList() since that wouldn't work with the Enum anyway). But sure, a custom UserType should work. You'd want to extract common stuff into a base class if you do this more than once. My preference would be to keep everything in the domain class if possible, as long as the changes aren't that significant.
Burt Beckwith
Burt, yes you're right i want to be able to set and get the status variable as an enum and also be able to save the database thus the use of the id in the enum. I'm leaning more toward a custom user type something along mapping= {status type:EnumUserType }
ken
Burt, Do you know if there is a bug in JIRA on this one? You ought to be able to give an Enum a sqlType in the mapping block.
Colin Harrington