Java “非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44258541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:26:34  来源:igfitidea点击:

“Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements”

javahibernateexceptioncollectionshibernate-mapping

提问by mh123hack

Good morning Stackoverflow,

早上好,

I have the problem that it gives me the error:

我有一个问题,它给了我错误:

Failed to create sessionFactory object.org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: nl.scalda.pasimo.model.employeemanagement.EducationTeam.coachGroups

无法创建 sessionFactory object.org.hibernate.AnnotationException:非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements:nl.scalda.pasimo.model.employeemanagement.EducationTeam.coachGroups

Do you know why?

你知道为什么吗?

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

采纳答案by cн?dk

The Exception is straightforward and says : Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements, so the cause is obvious here and if we take a look at the Hibernate Collection mappingdocumentationit clearly states that:

异常很简单,它说:非法尝试将非集合映射为@OneToMany、@ManyToMany 或 @CollectionOfElements,因此原因在这里很明显,如果我们查看Hibernate Collection 映射文档,它清楚地指出:

As a requirement persistent collection-valued fields must be declared as an interface type (see Example 7.2, “Collection mapping using @OneToMany and @JoinColumn”). The actual interface might be java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap...

作为一项要求,必须将持久集合值字段声明为接口类型(请参阅示例 7.2,“使用 @OneToMany 和 @JoinColumn 的集合映射”)。实际界面可能是java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap...

And you used TreeSetwhich is an implementation classfor both Set<E>and SortedSet<E>interfaces. So your actual mapping won't work with TreeSet, you should use a Set<CoachGroup>instead of a TreeSet<CoachGroup>:

而你使用TreeSet的是一个实现的都Set<E>SortedSet<E>接口。因此,您的实际映射不适用于TreeSet,您应该使用 aSet<CoachGroup>而不是 a TreeSet<CoachGroup>

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

回答by Nyamiou The Galeanthrope

You should map to interfaces and not implementations. This:

您应该映射到接口而不是实现。这个:

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

Should be (also replaced the TreeSet because a HashSet is enough here):

应该是(也替换了 TreeSet 因为这里有一个 HashSet 就足够了):

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

回答by Maciej Kowalski

You are not allowed to use a concrete implementation on the entities field declaration. You are allowed to use one of the following:

不允许在实体字段声明上使用具体实现。您可以使用以下之一:

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

So in your case it would have to be:

所以在你的情况下,它必须是:

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

回答by Obi Wan - PallavJha

You can't save your collection fields as Concrete classes.

您不能将集合字段保存为具体类。

Got this,

明白啦,

As a requirement persistent collection-valued fields must be declared as an interface type (see Example 7.2, “Collection mapping using @OneToMany and @JoinColumn”). The actual interface might be java.util.Set, java.util.Collection, java.util.List, java.util.Map, java.util.SortedSet, java.util.SortedMap or anything you like ("anything you like" means you will have to write an implementation of org.hibernate.usertype.UserCollectionType).

作为一项要求,必须将持久集合值字段声明为接口类型(请参阅示例 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 的实现)。

From Chapter 7. Collection Mapping.

来自第 7 章集合映射

You can use below code to save a sorted set(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<>();

回答by Wilson

Another possible reasons for this exception to occur is using a non-collection object for @ManyToManyand@OneToManymappings Or using collection object for @ManyToOneand @OneToOnemappings. All examples below are incorrect.

发生此异常的另一个可能原因是使用非集合对象 for @ManyToManyand @OneToManymappings 或使用集合对象 for @ManyToOneand @OneToOnemappings。下面的所有例子都是不正确的。

INCORRECT

不正确

 @ManyToMany
 private User user;

 @ManyToOne
 private User user;

 @OneToOne
 private List<User> users;

 @ManyToOne
 private List<User> users;