Search code examples
javahibernatejpahibernate-mapping

Hibernate: fetching objects collections without multiple bags


When I am trying to get list of my Employee entity I am getting this error:

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch 
multiple bags

My Employee entity class has two lists of different objects. I suppose there is problem.

@ManyToMany
@JoinTable(name = "employee_project",
        joinColumns = {@JoinColumn(name = "employee_id", referencedColumnName = "employee_id")},
        inverseJoinColumns = {@JoinColumn(name = "project_id", referencedColumnName = "project_id")})
protected List<Project> projects;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "employee_id")
protected List<EmployeeTheme> themes;

My entity Project doesn't have at this moment list of Employee objects. But

public class EmployeeTheme implements Serializable {

    @EmbeddedId
    private EmployeeTheme PK id;

    @ManyToOne
    @JoinColumn(name = "employee_id", nullable = false, insertable = false, updatable = false)
    protected Employee employee;
}

And this is my class for composite key:

@Embeddable
public class EmployeeThemePK implements Serializable {

    @Column(name = "employee_id")
    protected Long employeeId;

    @Column(name = "theme")
    protected String theme;
}

How can I properly configure these relations?

EDIT

I have switched List to Set for themes and projects. And I have excluded from my JSON themes and now I am getting another exception. I have also added criteria.setFetchMode("projects", FetchMode.JOIN); to method in my DAO class.

failed to lazily initialize a collection of role: com.package.Employee.projects,
no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a 
collection of role: com.package.Employee.projects, no session or session 
was closed


Exception caught during request processing: flexjson.JSONException: Error 
trying to deepSerialize
flexjson.JSONException: Error trying to deepSerialize

Solution

  • This exception is triggered because you're getting employees and eagerly fetching the employee's themes and the employee's projects.

    First, make sure you really really need both.

    Second, realize that by doing it like this, you're making a cartesian product. If an employee has 100 projects and 100 themes, the query will return 10,000 rows just for this employee. Maybe you should fetch the employee with its projects first (100 rows), and then refetch the employee with its themes (100 rows again).

    Third, if a cartesian product is really what you want, then make at least one of the collections a Set instead of a List.