web-dev-qa-db-fra.com

"Tentative illégale de mapper une non-collection en tant que @OneToMany, @ManyToMany ou @CollectionOfElements"

Bonjour Stackoverflow,

J'ai le problème que cela me donne l'erreur:

Échec de la création de sessionFactory object.org.hibernate.AnnotationException: Tentative illégale de mapper un non collection en tant que @OneToMany, @ManyToMany ou @CollectionOfElements: nl.scalda.pasimo.model.employeemanagement.EducationTeam.coachGroups

Est-ce que tu sais pourquoi?

@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);
    }
}
14
mh123hack

L'exception est simple et dit: Tentative illégale de mapper une non-collection en tant que @OneToMany, @ManyToMany ou @CollectionOfElements, donc la cause est évidente ici et si nous jetons un coup d'œil au Hibernate Cartographie de collection documentation il est clairement indiqué que:

En tant que condition requise, les champs de collection persistants doivent être déclarés en tant que type d'interface (voir Exemple 7.2, «Mappage de collection à l'aide de @OneToMany et @JoinColumn»). L’interface réelle peut être Java.util.Set, Java.util.Collection, Java.util.List, Java.util.Map, Java.util.SortedSet, Java.util.SortedMap...

Et vous avez utilisé TreeSet qui est une implémentation class pour les interfaces Set<E> et SortedSet<E>. Donc, votre correspondance ne fonctionnera pas avec TreeSet, vous devriez utiliser un Set<CoachGroup> au lieu d'un TreeSet<CoachGroup>:

private Set<CoachGroup> coachGroups = new HashSet<CoachGroup>();
15
cнŝdk

Vous devez mapper des interfaces et non des implémentations. Ce:

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

Devrait être (également remplacé le TreeSet car un HashSet suffit ici):

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

Vous ne pouvez pas enregistrer vos champs de collection en tant que classes concrètes. 

Je l'ai,

En tant que condition préalable, les champs à valeur de collection persistante doivent être déclarés en tant que type d'interface (voir Exemple 7.2, «Mappage de collection utilisant @OneToMany et @JoinColumn»). L’interface réelle pourrait être Java.util.Set, Java.util.Collection, Java.util.List, Java.util.Map, Java.util.SortedSet, Java.util.SortedMap ou tout ce que vous aimez ("tout ce que vous aimez" signifie que vous devrez écrire une implémentation de org.hibernate.usertype.UserCollectionType).

De Chapitre 7. Cartographie de collection .

Vous pouvez utiliser le code ci-dessous pour enregistrer un ensemble trié (KINDLY READ THE COMMENTS):

@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<>();
0

Vous n'êtes pas autorisé à utiliser une implémentation concrète sur la déclaration de zone des entités. Vous êtes autorisé à utiliser l'un des éléments suivants:

  • Java.util.List
  • Java.util.Set
  • Java.util.Collection

Donc, dans votre cas, il faudrait que ce soit:

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