Multiple objects created for one-to-many assocation

This seems to be a very fundamental scenario to me but I cannot find an answer anywhere.

I have three entities. A Parent entity that has a one-to-many association to Child entities and the Child entity has a one-to-many assocation with GrandChild entities.

public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Parent_ID", nullable = false)
    private Integer id;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade =CascadeType.ALL, orphanRemoval = true)
    private Set<Child> children;
}
public class Child {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Child_ID", nullable = false)
    private Integer id;

   @ManyToOne
    @JoinColumn(name = "Parent_ID")
    private Parent parent;

    @OneToMany(mappedBy = "child", fetch = FetchType.LAZY, cascade =CascadeType.ALL, orphanRemoval = true)
    private Set<GrandChild> grandChildren;
}
public class GrandChild {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "GrandChild_ID", nullable = false)
    private Integer id;

   @ManyToOne
    @JoinColumn(name = "Child_ID")
    private Child child;
}

Using the code below I get a HibernateException: collection evicted error. I assume this is because it has retrieved multiple rows from the database and is trying to return a collection instead of just one Parent record with multiple children where each child has multiple grandchildren, which is what I want. What am I doing wrong? Or is my expectation incorrect?

public Parent test(Integer id) {
        CriteriaBuilder criteriaBuilder = this.getSession().getCriteriaBuilder();
        CriteriaQuery<Parent> criteriaQuery = criteriaBuilder.createQuery(Parent.class);
        Root<Parent> parent = criteriaQuery.from(Parent.class);

        Fetch<Parent , Child> childFetch = parent .fetch("children", JoinType.LEFT);
        Fetch<Child, GrandChild> grandChildFetch = childFetch.fetch("grandChildren", JoinType.LEFT);

        criteriaQuery.where(criteriaBuilder.equal(parent.get("id"), id));
        return this.getSession().createQuery(criteriaQuery).getSingleResult();
}

This should work just fine, which Hibernate ORM version are you using?

I am using 5.6.15.Final

Please upgrade to the latest version then, 6.3.1.Final or 6.4.0.CR1. Hibernate ORM 5 only receives limited support at this time, so chances are that even if you find a bug, it won’t be fixed.