“非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements”
Posted
技术标签:
【中文标题】“非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements”【英文标题】:“Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements” 【发布时间】:2017-10-30 17:02:47 【问题描述】:早上好 ***,
我的问题是它给了我错误:
创建会话工厂失败 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);
【问题讨论】:
你为什么用TreeSet
而不是Set
?!
【参考方案1】:
异常很简单,说:非法尝试将非集合映射为@OneToMany、@ManyToMany 或@CollectionOfElements,所以原因在这里很明显,如果我们看看@ 987654321@它明确指出:
作为要求,必须将持久集合值字段声明为接口类型(参见示例 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】:发生此异常的另一个可能原因是使用非集合对象
@ManyToMany
和@OneToMany
映射或将集合对象用于@ManyToOne
和@OneToOne
映射。以下所有示例均不正确。
不正确
@ManyToMany
private User user;
@ManyToOne
private User user;
@OneToOne
private List<User> users;
@ManyToOne
private List<User> users;
【讨论】:
感谢您的回答...我遇到了同样的问题@ManyToMany private User user
【参考方案4】:
您不能将集合字段保存为具体类。
知道了,
作为要求,必须声明持久的集合值字段 作为接口类型(参见示例 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)。
来自Chapter 7. Collection Mapping。
您可以使用以下代码来保存排序集:
请务必阅读 cmets
@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<>();
【讨论】:
【参考方案5】:您不能在实体字段声明中使用具体实现。您可以使用以下其中一项:
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<>();
【讨论】:
以上是关于“非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements”的主要内容,如果未能解决你的问题,请参考以下文章