Reputation: 882
I have an enum with a hibernate custom UserType:
enum Program { ABC(1000), XYZ(1001); final long code; ... }
class ProgramUserType implements org.hibernate.usertype.UserType { ... }
The ProgramUserType stores the code (1000, 1001, etc) for the enum and gets the enum instance back via the code when read from the database.
This is in use successfully on a relationship in a domain class:
class MyDomainOne {
Program program
...
static mapping = {
...
program column: 'PROGRAM_ID', type: ProgramUserType
...
}
}
So, all of the above works fine.
But I want to use the enum in a hasMany relationship:
class MyDomainTwo {
...
static hasMany = [
programs: Program
]
...
static mapping = {
...
programs joinTable: [name: 'BLAH_DOM_TWO_PROGS', key: 'DOM_TWO_ID', column: 'PROGRAM_ID']
...
}
}
My issue is that always produces a column with a "varchar2(255 char)" type:
BLAH_DOM_TWO_PROGS (DOM_TWO_ID number(19,0) not null, PROGRAM_ID varchar2(255 char));
I've tried various things to no avail:
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: [...]
etc.
What is the proper syntax to use a custom user type in a join table mapping?
(I'm using grails 2.3.7)
Upvotes: 2
Views: 796
Reputation: 534
I don't know why you do this complex but in order to write a code(Integer, Long, String...) into a column of database from an enum, you can implement simply like this:
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() }
}
The importance line of code is Integer getId() { id }
You can change id property to whatever type you want.
Hope it help
some reference links GRAILS-3633 or in another discussion
Upvotes: 3
Reputation: 50245
type
cannot be specified for the inverse column in joinTable. It looks like one should be able to mention any other column config from this line but it does not work. You can raise a JIRA issue as enhancement/bug/feature request and/or drop the idea of using joinTable
but create an actual domain class to handle the XRef table. For example, in lines of something like:
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'
}
}
with
class MyDomainTwo {
def getPrograms() {
DomainProgram.findByMyDomain(this)*.programId.collect {
Program.getEnum it
}
}
}
and
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 }
}
}
There will be a little bit of boiler plate code involved like implementing equals()
and hasCode()
in DomainProgram
but will create the columns as desired.
Upvotes: 1