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

61,232

Solution 1

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 mapping documentation it clearly states that:

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...

And you used TreeSet which is an implementation class for 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>:

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

Solution 2

Another possible reasons for this exception to occur is using a non-collection object for @ManyToMany and@OneToMany mappings Or using collection object for @ManyToOne and @OneToOne mappings. All examples below are incorrect.

INCORRECT

 @ManyToMany
 private User user;

 @ManyToOne
 private User user;

 @OneToOne
 private List<User> users;

 @ManyToOne
 private List<User> users;

Solution 3

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):

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

Solution 4

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).

From Chapter 7. Collection Mapping.

You can use below code to save a sorted set:

Please do read the comments too

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

Solution 5

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

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<>();
Share:
61,232
mh123hack
Author by

mh123hack

Updated on August 18, 2021

Comments

  • mh123hack
    mh123hack over 2 years

    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

    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);
        }
    }
    
  • DirtyMind
    DirtyMind about 3 years
    Thanks for this answer... I had the same issue @ManyToMany private User user