Отображение карт Grails
в Grails, есть ли способ ограничить размер столбца, на который отображается перечисление. В следующем примере я хотел бы, чтобы тип столбца был 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)
}
}
как inList, так и размер не влияют при экспорте схемы, тип столбца сохраняет свое значение по умолчанию (varch (255))
Возможно, я мог бы это сделать, если бы я определил новый UserType. Любая идея?
Спасибо.
-ken
Ответы
Ответ 1
Я не думаю, что это возможно напрямую, учитывая, как перечисления отображаются внутри GORM. Но изменение кода на это работает:
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 }
}
}
и
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)'
}
}
Добавление переходного приемника и сеттера позволяет вам установить или получить либо значение String (id), либо значение enum.
Ответ 2
Grails поставляется с недокументированным (насколько я могу судить, так или иначе) пользовательским сопоставлением Hibernate для перечислений. Класс - org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType. Он не позволит вам установить размер столбца, но облегчит изменение того, что хранится в БД для каждого значения перечисления, без необходимости добавлять переходные поля к вашей модели.
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 }
}
}
Вы можете запустить "alter table" в Bootstrap.groovy, чтобы сжать столбец:
DataSource dataSource
...
Sql sql = new Sql(dataSource)
sql.execute("alter table my_domain_class change column status status varchar(1) not null")
Ответ 3
Еще проще (работает хотя бы в 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
}
}
Ответ 4
Так как сопоставление идентификаторов GORM 6.1 может быть включено с такой конструкцией
static mapping = {
myEnum enumType:"identity"
}