Коллекция карт JPA из Enums

Есть ли способ в JPA сопоставить коллекцию Enums в classе Entity? Или единственным решением является обернуть Enum другим classом домена и использовать его для сопоставления коллекции?

@Entity public class Person { public enum InterestsEnum {Books, Sport, etc... } //@??? Collection interests; } 

Я использую Hibernate JPA, но, конечно, предпочла бы реализацию агностического решения.

используя Hibernate, вы можете сделать

 @CollectionOfElements(targetElement = InterestsEnum.class) @JoinTable(name = "tblInterests", joinColumns = @JoinColumn(name = "personID")) @Column(name = "interest", nullable = false) @Enumerated(EnumType.STRING) Collection interests; 

Ссылка в ответе Энди – отличная отправная точка для сопоставления наборов объектов «не-Entity» в JPA 2, но не совсем полна, когда дело доходит до отображения перечислений. Вот что я придумал вместо этого.

 @Entity public class Person { @ElementCollection(targetClass=InterestsEnum.class) @Enumerated(EnumType.STRING) // Possibly optional (I'm not sure) but defaults to ORDINAL. @CollectionTable(name="person_interest") @Column(name="interest") // Column name in person_interest Collection interests; } 

Я использую небольшую модификацию java.util.RegularEnumSet, чтобы иметь постоянный EnumSet:

 @MappedSuperclass @Access(AccessType.FIELD) public class PersistentEnumSet> extends AbstractSet { private long elements; @Transient private final Class elementType; @Transient private final E[] universe; public PersistentEnumSet(final Class elementType) { this.elementType = elementType; try { this.universe = (E[]) elementType.getMethod("values").invoke(null); } catch (final ReflectiveOperationException e) { throw new IllegalArgumentException("Not an enum type: " + elementType, e); } if (this.universe.length > 64) { throw new IllegalArgumentException("More than 64 enum elements are not allowed"); } } // Copy everything else from java.util.RegularEnumSet // ... } 

Этот class теперь является базой для всех моих наборов перечислений:

 @Embeddable public class InterestsSet extends PersistentEnumSet { public InterestsSet() { super(InterestsEnum.class); } } 

И этот набор, который я могу использовать в своей сущности:

 @Entity public class MyEntity { // ... @Embedded @AttributeOverride(name="elements", [email protected](name="interests")) private InterestsSet interests = new InterestsSet(); } 

Преимущества:

  • Работа с типом безопасного и исполняемого enums, установленного в вашем коде (см. java.util.EnumSet для описания)
  • Набор представляет собой только один числовой столбец в базе данных
  • все это простой JPA ( нестандартные типы поставщиков)
  • легкое (и короткое) объявление новых полей того же типа, по сравнению с другими решениями

Недостатки:

  • Дублирование кода ( RegularEnumSet и PersistentEnumSet почти одинаковы)
    • Вы можете обернуть результат EnumSet.noneOf(enumType) в свой PersistenEnumSet , объявить AccessType.PROPERTY и предоставить два метода доступа, которые используют reflection для чтения и записи поля elements
  • Для каждого classа enums, который должен храниться в постоянном наборе, необходим дополнительный class набора
    • Если ваш провайдер персистентности поддерживает вложенные @Embeddable без общего конструктора, вы можете добавить @Embeddable в PersistentEnumSet и удалить дополнительный class ( ... interests = new PersistentEnumSet<>(InterestsEnum.class); )
  • Вы должны использовать @AttributeOverride , как указано в моем примере, если у вас более одного PersistentEnumSet в вашей сущности (иначе оба будут сохранены в те же элементы столбца)
  • Доступ values() с reflectionм в конструкторе не является оптимальным (особенно при просмотре производительности), но у двух других вариантов есть свои недостатки:
    • Реализация, такая как EnumSet.getUniverse() использует class sun.misc
    • Предоставление массива значений в качестве параметра имеет риск того, что данные значения не являются правильными
  • Поддерживаются только enums с до 64 значениями (это действительно недостаток?)
    • Вместо этого вы можете использовать BigInteger
  • Нелегко использовать поле элементов в критерии запроса или JPQL
    • Вы можете использовать двоичные операторы или битмакс-столбец с соответствующими функциями, если ваша firebase database поддерживает это

Я смог выполнить это простым способом:

 @ElementCollection(fetch = FetchType.EAGER) Collection interests; 

Желательная загрузка необходима, чтобы избежать ленивой ошибки инициализации загрузки, как описано здесь .

Коллекции в JPA относятся к отношениям один-ко-многим или многим ко многим, и они могут содержать только другие сущности. Извините, но вам нужно будет обернуть эти enums в сущности. Если вы подумаете об этом, вам понадобится какое-то поле идентификатора и внешний ключ, чтобы сохранить эту информацию в любом случае. То есть, если вы не делаете что-то безумное, как хранить список, разделенный запятыми, в String (не делайте этого!).

  • Как просмотреть SQL-запросы, выпущенные JPA?
  • Как вызвать функцию или процедуру Oracle с помощью Hibernate (EntityManager) или JPA 2
  • JPA нетерпеливый выбор не присоединяется
  • JPA getSingleResult () или null
  • JPA OneToMany, не удаляющий ребенка
  • Уникальное ограничение с JPA и проверкой Bean
  • Как аннотировать поле автоинкремента MYSQL с аннотациями JPA
  • Спящий режим и без ПК
  • Неправильное упорядочение в сгенерированной таблице в jpa
  • Как правильно настроить EntityManager в приложении jersey / hk2?
  • Тип выборки по умолчанию для одного-к-одному, много-к-одному и один-ко-многим в спящем режиме
  • Interesting Posts

    Как преобразовать изображение RGB в оттенки серого, но сохранить один цвет?

    Несколько заказов с помощью LINQ

    Доступ к коду в Swift 3 Error

    Почему вложенные веса плохо подходят для производительности? Альтернативы?

    Хотя в сеансе удаленного рабочего стола в Windows 7, Alt-Tab, чтобы вернуться к главной машине

    Когда в Scala требуется @uncheckedVariance и почему она используется в GenericTraversableTemplate?

    Создание допустимого XML с кодировкой Java и UTF-8

    Как сделать тип зависимым от значения атрибута с помощью присвоения условного типа

    Возврат старого поведения переключения окон Alt-Tab в Windows 7

    Как я могу получить размер блока памяти, выделенного с помощью malloc ()?

    Основной код метода полностью внутри try / catch: это плохая практика?

    Добавить схему «Область поиска» на результат Google Maps

    Шаблон Spring JDBC для вызова хранимых процедур

    TwitteR, ROAuth и Windows: зарегистрируйтесь в порядке, но проверка сертификата не выполнена

    BULK INSERT в MYSQL

    Давайте будем гением компьютера.