2009-10-20 9 views
16

Ich muss die Enums, die die Schnittstelle nicht zuvor an die vorhandene Datenbank, die Enums in der gleichen Tabelle wie die Besitzer-Klasse mit der @Enumerated(EnumType.STRING) speichert.Hibernate-Enum-Zuordnung

class A { 
    HasName name; 
} 

interface HasName { 
    String getName(); 
} 

enum X implements HasName { 
    John, Mary; 

    public String getName() { return this.name(); } 
} 

enum Y implements HasName { 
    Tom, Ann; 

    public String getName() { return this.name(); } 
} 

Wie sollte das Mapping in diesem Fall behandelt werden? Die Speicherung in der Datenbank ändert sich nicht, da alle enums, die die Schnittstelle implementieren, unterschiedliche Werte haben werden, aber ich bin mir nicht sicher, wie die Objekte aus der DB abgerufen werden sollen (brauche ich einen benutzerdefinierten Mapper, der versucht, einen zu instanziieren) Enum mit den angegebenen Enum-Klassen? Unterstützt Hibernate nativ diese Funktionalität?).

Antwort

7

Es ist möglich, einen benutzerdefinierten UserType (zB this one) und verwenden Sie es von Ihrem Mappings

<property name="type" not-null="true"> 
    <type name="at.molindo.util.hibernate.EnumUserType"> 
    <param name="enumClass"> 
     com.example.MyEnum 
    </param> 
    </type> 
</property> 

EDIT zu erstellen: Hibernate kommt mit seinem eigenen EnumType (seit 3.2 in Hibernate-Annotationen, da 3.6 in Hibernate-Core - wusste zum Zeitpunkt des Schreibens nicht, dass es sich um Hibernate-Anmerkungen handelt, aber siehe Diego's answer).

+0

In meinem Fall ich weiß nicht, was die Klasse der Enumeration sein wird. Wenn Sie "A" instanziieren, muss Hibernate eines der {X, Y} -Enums auswählen. – dm3

+0

Es sollte nicht schwierig sein, die Beispiel-UserType-Implementierung an Ihre Bedürfnisse anzupassen. Anstatt beispielsweise nur den Wert zu speichern, können Sie auch die Klasse speichern (zB com.example.X.John oder X.John, aber dann brauchen Sie eine Zuordnung von X zu com.example.X) – sfussenegger

+0

Means I brauche einen benutzerdefinierten Mapper (habe deinen Link zu Pastebin nicht gesehen). Danke für die Antwort. – dm3

50

Hibernate stellt org.hibernate.type.EnumType zur Auflistung von Aufzählungstypen bereit. Zum Beispiel

package com.igalia.enumerates; 

public enum Status { 
    BUSY, 
    AVAILABLE; 
} 

package com.igalia.entities; 

class MyClass { 
    private Status status; 
} 

Dann machen Sie Ihre Hibernate Mapping wie folgt:

<class name="MyClass"> 
    <id name="id"> 
     <generator class="native"/> 
    </id> 

    <property name="status"> 
     <type name="org.hibernate.type.EnumType"> 
     <param name="enumClass">com.igalia.enumerates.Status</param> 
     </type> 
    </property> 
</class> 

Und das ist es. Wenn Sie JPA-Annotationen anstelle von hbm.xml verwenden möchten, verwenden Sie @Enumerated (EnumType.STRING). Prüfen Sie es hier:

Enumerations in Hibernate

+0

Wie legen Sie einen Standardwert dafür fest? Ich habe das folgende Element zu hinzugefügt, aber das hat bei mir nicht funktioniert: Timo

+1

@valmar Sie können * status * auf Klassenebene (oder in seinem Konstruktor) initialisieren. Zum Beispiel: 'Privater Statusstatus = Status.BUSY;' –