Перелічення в сплячому режимі


82

Часто корисно мати поле в DAO, значення якого походить від перерахування Java. Типовим прикладом є DAO для входу, де зазвичай у вас є поле, яке характеризує користувача як "ЗВИЧАЙНИЙ" або "АДМІНІСТРАТОР". У режимі глибокого сну я використовував би наступні 2 об’єкти для представлення цього відношення у (напів-) безпечному типі:

class User {
    String username;
    String passwd;
    UserType type;
}

class UserType {
    private enum Type {ADMIN, NORMAL};
    private String type;

    //Setters/Getters for Hibernate
    public void setType(String type);
    public String getType();

    //Setters/Getters for user
    public void setUserType(UserType.Type t);
    public UserType.Type getUserType();

    public static UserType fromType(UserType.Type t);
}

Це працює, але я вважаю клас UserType потворним і вимагає занадто багато бюрократії, щоб просто зберегти пару значень. В ідеалі Hibernate повинен безпосередньо підтримувати поля перерахування та створити додаткову таблицю для зберігання значень перерахування.

Моє запитання: чи є якийсь спосіб безпосередньо зіставити клас перерахування в сплячому режимі? Якщо ні, то чи достатньо хороший мій шаблон для подання переліків чи мені чогось не вистачає? Які ще моделі використовують люди?

Відповіді:


110

використання анотацій сплячого режиму або JPA:

class User {
   @Enumerated(EnumType.STRING)
   UserType type
}

UserType - це просто стандартний перелік Java 5.

Я не можу уявити, що це обмежується лише анотаціями, але я насправді не знаю, як це зробити з файлами hbm. Це може залежати від версії, я здогадуюсь, але я впевнений, що потрібен режим глибокого сну 3.2+.

редагувати: це можливо в hbm, але трохи брудно, погляньте на цю тему форуму


3
Чи міг @Enumerated (EnumType.ORDINAL), яку карту вводити більш ефективною?
Lee Chee Kiam

4
імовірно, це ефективніше, але я б поклав гроші на те, що не можу виміряти різницю в реальній системі. EnumType.ORDINAL насправді є типовим за замовчуванням, якщо ви просто робите @Enumerated. Я думаю, що більшість людей (зокрема DBA), як правило, віддають перевагу імені переліку в БД.
Gareth Davis

1
Як я можу змінити довжину стовпця для цих перерахувань? Я спробував додати анотацію Стовпець, але це не отримує почестей?
Kannan Ekanath,

2
Вам потрібно поставити це як ще одне питання.
Gareth Davis

2
Використовуйте STRING, а не ORDINAL, оскільки це дозволяє додавати додаткові елементи до Enum незалежно від замовлення.
Метью Домен

14

З документації про сплячий режим: http://www.hibernate.org/272.html

Ви можете створити новий typedef для кожного з ваших перерахувань і посилатися на typedefs у тезі властивостей.

Приклад зіставлення - вбудований <type>тег

  <property name='suit'>
    <type name="EnumUserType">
      <param name="enumClassName">com.company.project.Suit</param>
    </type>
  </property>

Приклад картографування - використання <typedef>

  <typedef name="suit" class='EnumUserType'>
      <param name="enumClassName">com.company.project.Suit</param>
  </typedef>

  <class ...>
    <property name='suit' type='suit'/>
  </class>

Дякую. Я вже знав про це рішення. Проблема полягає в тому, що вона вимагає, щоб усі ваші перерахування використовували внутрішні типи глибокого сну, що може спричинити проблеми, якщо ви використовуєте DAO як DTO, як у моєму випадку. Краще рішення насправді описано тут: hibernate.org/273.html
Георгіос Гусіос

1
Зверніть увагу, що в новіших версіях ім'я параметра enumClassзамість enumClassName.
Райан Ренсфорд,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.