2009-10-20 3 views
16

Мне нужно отобразить перечисления, которые заранее не реализовали интерфейс к существующей базе данных, которая хранит перечисления в той же таблице, что и класс владельца, используя @Enumerated(EnumType.STRING).Отображение перечисления Hibernate

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

Как должно обрабатываться отображение в этом случае? Сохранение базы данных не изменяется, поскольку все перечисления, реализующие интерфейс, будут иметь разные значения, но я не уверен, как объекты должны быть извлечены из БД (нужен ли мне настраиваемый сопоставитель, который попытается создать экземпляр enum с использованием указанных классов enum? Поддерживает ли Hibernate эту функциональность?).

ответ

7

Можно создать собственный UserType (например this one) и использовать его из ваших отображений

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

EDIT: Hibernate поставляется с собственным EnumType (с 3,2 в Hibernate-аннотации, так как 3.6 в спящем-ядра - не знал о том, что он был в hibernate-аннотации на момент написания, но см. Diego's answer).

+0

В моем случае я не знаю, что будет класс перечисления. При создании экземпляра 'A', Hibernate нужно будет выбрать одну из перечней {X, Y}. – dm3

+0

Не следует пытаться настроить пример реализации UserType в соответствии с вашими потребностями. Например, вместо сохранения только значения вы можете также сохранить класс (например, com.example.X.John или X.John, но вам понадобится сопоставление от X до com.example.X) – sfussenegger

+0

Средства I нужен пользовательский сопоставитель (не видел вашу ссылку на pastebin). Спасибо за ответ. – dm3

50

Hibernate предоставляет org.hibernate.type.EnumType, чтобы перечислить Перечисленные типы. Например,

package com.igalia.enumerates; 

public enum Status { 
    BUSY, 
    AVAILABLE; 
} 

package com.igalia.entities; 

class MyClass { 
    private Status status; 
} 

Затем, сделайте свое отображение гибернации следующим образом:

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

И это все. Если вы предпочитаете использовать JPA-аннотации вместо hbm.xml, используйте @Enumerated (EnumType.STRING). Проверьте это здесь:

Enumerations in Hibernate

+0

Как вы устанавливаете для этого значение по умолчанию? Я добавил следующий элемент в , но это не сработало для меня: Timo

+1

@valmar вы можете инициализировать * статус * на уровне класса (или делать это в своем конструкторе). Например, «статус статуса статуса = статус.BUSY;» –

Смежные вопросы