Das mit Java 5 eingeführte Aufzählungsobjekt Enum
ist in vielerlei
Fällen äußerst hilfreich. Der komfortable Einsatz dieses Datentypen in
Grails gestaltet sich mitunter allerdings etwas trickreich.
Zur Verdeutlichung des Problems greifen wir auf eine Person zurück,
dessen Fähigkeiten wir abbilden wollen. In unserem Falle handelt es sich
dabei um ein festen Satz an Fähigkeiten, der unveränderlich ist und den
wir daher wir als Skill
in Form eines Aufzählungsobjektes darstellen
möchten. Die Person und ihre Fähigkeiten werden anschließend über eine
1:n Beziehung miteinander verknüpft.
Mein ursprünglicher Gedanke sieht daher folgendermaßen aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person { String name static hasMany = [skills: Skill] static constraints = { name blank: false } } enum Skill { CODING, GAMING, SKIING; } |
Beim Versuch diese Beziehung zu persistieren rennen wir allerdings in
eine java.lang.ClassCastException
mit der Meldung java.lang.String
cannot be cast to java.lang.Enum hinein. Anscheinend versucht GORM an
dieser Stelle unser Aufzählungsobjekt in eine Zeichenkette zu pressen,
was jedoch kläglich scheitert.
Mit Version 1.1 Beta 2 von Grails wurde die erweiterte Unterstützung
von Enum
integriert.
Dabei bezieht GORM
nun den zu persistierenden Wert über die Methode
getId()
von dem Enum
. Daher wandeln wir unseren Code wie folgt ab:
1 2 3 4 5 6 7 8 9 | enum Skill { CODING('C'), GAMING('G'), SKIING('S'); final String id Skill(String id) { this.id = id } } |
Bei der Persistierung stoßen wir nun nicht mehr auf eine
java.lang.ClassCastException
, allerdings auch nicht auf die Lösung des
Problems, da unsere Werte als NULL
in der Datenbank untergebracht
werden.
Nach einiger Tüftelei bin ich auf folgenden Workaround gestoßen, wobei
wir die Elemente von skills
als String
definieren:
1 2 3 4 5 6 7 | class Person { String name static hasMany = [skills: String] static constraints = { name blank: false } } |
Es läuft zwar, allerdings hätte ich mir gewünscht das GORM
selbstständig in der Lage gewesen wäre den Datentyp von getId()
zu
ermitteln und entsprechend zu berücksichtigen.