"Незаконная попытка сопоставить не коллекцию как @OneToMany, @ManyToMany или @CollectionOfElements"

Доброе утро, Stackoverflow,

У меня есть проблема, что он дает мне ошибку:

Не удалось создать sessionFactory object.org.hibernate.AnnotationException: Незаконная попытка сопоставить не коллекции как @OneToMany, @ManyToMany или @CollectionOfElements: nl.scalda.pasimo.model.employeemanagement.EducationTeam.coachGroups

Знаете ли вы, почему?

@OneToMany(cascade=CascadeType.ALL, targetEntity=CoachGroup.class)
@JoinColumn(name="id")
private TreeSet<CoachGroup> coachGroups = new TreeSet<>();
private SessionFactory factory;

private void initialiseFactory() {
    try {
        factory = new Configuration().configure().buildSessionFactory();
    } catch (Throwable ex) {
        System.err.println("Failed to create sessionFactory object." + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

Ответ 1

Исключение является простым и говорит: "Недопустимая попытка отобразить не коллекцию как @OneToMany, @ManyToMany или @CollectionOfElements, поэтому причина здесь очевидна, и если мы посмотрим на документацию по отображению Коллекции Hibernate, то она ясно заявляет, что:

В качестве требования постоянные коллекционные поля должны быть объявлены как тип интерфейса (см. Пример 7.2, "Отображение коллекции с использованием @OneToMany и @JoinColumn"). Фактический интерфейс может быть java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap...

И вы использовали TreeSet, который является классом реализации для интерфейсов Set<E> и SortedSet<E>. Таким образом, ваше фактическое отображение не будет работать с TreeSet, вы должны использовать Set<CoachGroup> вместо TreeSet<CoachGroup>:

private Set<CoachGroup> coachGroups = new HashSet<CoachGroup>();

Ответ 2

Вам следует сопоставить интерфейсы, а не реализации. Это:

@OneToMany(cascade=CascadeType.ALL, targetEntity=CoachGroup.class)
@JoinColumn(name="id")
private TreeSet<CoachGroup> coachGroups = new TreeSet<>();

Должен быть (также заменен TreeSet, потому что здесь достаточно HashSet):

@OneToMany(cascade=CascadeType.ALL, targetEntity=CoachGroup.class)
@JoinColumn(name="id")
private Set<CoachGroup> coachGroups = new HashSet<>();

Ответ 3

Вам не разрешается использовать конкретную реализацию в декларации полей сущностей. Вам разрешено использовать одно из следующих действий:

  • java.util.List
  • java.util.Set
  • java.util.Collection

Итак, в вашем случае это должно быть:

@OneToMany(cascade=CascadeType.ALL, targetEntity=CoachGroup.class)
@JoinColumn(name="id")
private Set<CoachGroup> coachGroups = new TreeSet<>();

Ответ 4

Вы не можете сохранять свои поля коллекции как классы Concrete.

Получив это,

В качестве требования должны быть объявлены постоянные поля, содержащие коллекцию как тип интерфейса (см. пример 7.2, "Отображение коллекции с использованием @OneToMany и @JoinColumn" ). Фактический интерфейс может быть java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap или что-нибудь, что вам нравится ( "что угодно" означает, что вам нужно будет написать реализацию org.hibernate.usertype.UserCollectionType).

Из Глава 7. Картирование коллекции.

Вы можете использовать приведенный ниже код, чтобы сохранить отсортированный набор (НЕПРАВИЛЬНО ПРОЧИТАЙТЕ КОММЕНТАРИИ):

@OneToMany(cascade=CascadeType.ALL) //Removed targetEntity, as you are already using generics.
@JoinColumn(name="team_id") // Use this name as to show the presence of foreign key of EducationTeam in CoachGroup.
@SortNatural // Make sure that your CoachGroup Entity has implemented Comparable<CoachGroup> interface which wii be used while sorting.
private SortedSet<CoachGroup> coachGroups = new TreeSet<>();