Grails有很多带有自定义hibernate UserType的枚举

时间:2014-08-05 21:06:51

标签: hibernate grails gorm

我有一个带有hibernate自定义UserType的枚举:

enum Program { ABC(1000), XYZ(1001); final long code; ... }

class ProgramUserType implements org.hibernate.usertype.UserType { ... }  

ProgramUserType存储枚举的代码(1000,1001等),并在从数据库读取时通过代码获取枚举实例。

这已成功用于域类中的关系:

class MyDomainOne {
    Program program
    ...
    static mapping = {
        ...
        program column: 'PROGRAM_ID', type: ProgramUserType
        ...
    }
}

所以,以上所有工作都很好。

但我想在hasMany关系中使用枚举:

class MyDomainTwo {
    ...
    static hasMany = [
        programs: Program
    ]
    ...
    static mapping = {
        ...
        programs joinTable: [name: 'BLAH_DOM_TWO_PROGS', key: 'DOM_TWO_ID', column: 'PROGRAM_ID']
        ...
    }
}

我的问题是始终生成一个带有" varchar2(255 char)"的列。类型:

BLAH_DOM_TWO_PROGS (DOM_TWO_ID number(19,0) not null, PROGRAM_ID varchar2(255 char));

我尝试了各种各样的事情无济于事:

programs joinTable: [name: 'BLAH_DOM_TWO_PROGS', key: 'DOM_TWO_ID', column: 'PROGRAM_ID', type: ProgramUserType]

programs joinTable: [name: 'BLAH_DOM_TWO_PROGS', key: 'DOM_TWO_ID', column: 'PROGRAM_ID', type: ProgramUserType, sqlType: 'NUMBER(10,0)']

programs type: ProgramUserType, joinTable: [...]

在连接表映射中使用自定义用户类型的正确语法是什么?

(我使用的是grails 2.3.7)

2 个答案:

答案 0 :(得分:3)

我不知道你为什么这么复杂但是为了从枚举中将代码(Integer,Long,String ...)写入数据库列,你可以像这样实现:

enum Program {
    ABC(0, "ABC"),
    XYZ(1, "XYZ"),

    final String value
    final Integer id

    Program(Integer value, String selectValue) {
        this.id = value
        this.value = selectValue
    }

    //https://github.com/tudor-malene/Easygrid/issues/22
    //shows value in select drop down
    String toString() { value }

    //stores value in database
    Integer getId() { id }

    //returns Enum constant associated with value
    String getKey(){ name() }
}

代码的重要性是Integer getId() { id } 您可以将id属性更改为您想要的任何类型。 希望有所帮助

一些参考链接GRAILS-3633in another discussion

答案 1 :(得分:1)

无法为joinTable中的反向列指定

type。看起来应该能够提及this line中的任何其他列配置,但它不起作用。您可以将JIRA问题提升为增强/错误/功能请求和/或放弃使用joinTable的想法,但创建一个实际的域类来处理XRef表。例如,在以下行中:

class DomainProgram implements Serializable {

    MyDomainTwo myDomain
    Long programId

    static mapping = {
        id composite: ['myDomain', 'programId']
        table 'DOMAIN_PROGRAM'
        myDomain column: 'DOMAIN_ID'
        programId column: 'PROGRAM_ID'
    }
}

class MyDomainTwo {
    def getPrograms() {
        DomainProgram.findByMyDomain(this)*.programId.collect { 
            Program.getEnum it 
        }
    }
}

enum Program {
    ABC(1000), XYZ(1001)

    final long code

    private Program(long _code) {
        code = _code
    }

    long getValue() {
        code
    }

    static Program getEnum(long value) {
        values().find { it.code == value }
    }
}

将涉及一些锅炉板代码,例如在equals()中实施hasCode()DomainProgram,但会根据需要创建列。