2009-10-20 10 views
16

Potrzebuję odwzorować wyliczenia, które wcześniej nie implementowały interfejsu do istniejącej bazy danych, która przechowuje wyliczenia w tej samej tabeli, co klasa właściciela przy użyciu @Enumerated(EnumType.STRING).Mapowanie wyliczanie hibernacji

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(); } 
} 

Jak w takim przypadku należy wykonać mapowanie? Utrzymywanie bazy danych nie zmienia się, ponieważ wszystkie enumy implementujące interfejs będą miały różne wartości, ale nie jestem pewien, w jaki sposób obiekty powinny być pobierane z DB (czy potrzebuję niestandardowego programu odwzorowującego, który spróbuje utworzyć instancję enum przy użyciu określonych klas wyliczeniowych? Czy Hibernate natywnie obsługuje tę funkcję?).

Odpowiedz

7

Jest możliwe, aby utworzyć niestandardowy UserType (np this one) i używać go ze swoimi odwzorowań

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

EDIT: Hibernate pochodzi z jego własnych EnumType (od 3.2 w hibernate-adnotacji, od 3,6 w hibernacji-core - nie wiedział o tym, że jest w hibernacji-adnotacje w momencie pisania, ale zobacz Diego's answer).

+0

W moim przypadku nie wiem, co będzie klasa wyliczenia. Podczas tworzenia 'A', Hibernate będzie musiał wybrać jedną z wymień {X, Y}. – dm3

+0

Nie powinno być trudno dopasować przykładową implementację UserType do twoich potrzeb. Na przykład, zamiast zapisywania tylko wartości, możesz również przechowywać klasę (np. Com.example.X.John lub X.John, ale będziesz potrzebować mapowania z X na com.example.X) – sfussenegger

+0

Znaczy I Potrzebujemy niestandardowego programu odwzorowującego (nie widziałem twojego linku do pastebin). Dziękuję za odpowiedź. – dm3

50

Hibernate udostępnia org.hibernate.type.EnumType do mapowania typów wyliczeniowych. Na przykład,

package com.igalia.enumerates; 

public enum Status { 
    BUSY, 
    AVAILABLE; 
} 

package com.igalia.entities; 

class MyClass { 
    private Status status; 
} 

Następnie wykonać mapowanie hibernacji w następujący sposób:

<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> 

I to wszystko. Jeśli wolisz używać adnotacji JPA zamiast hbm.xml, użyj @Enumerated (EnumType.STRING). Sprawdź to tutaj:

Enumerations in Hibernate

+0

Jak ustawić domyślną wartość? Dodałem następujący element do , ale to nie działało dla mnie: Timo

+1

@valmar można zainicjować * status * na poziomie klasy (lub zrobić to w swoim konstruktorze). Na przykład "prywatny status statusu = status.BUSY;" –