Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate fetch join -> cannot fetch multiple bags

Problem is i have two bags in my entity which i would like to display in my jsf frontend (Spring in the back so no lazy loading). So i have to eagerly fetch them to display the information in a list like this:

  • Point 1 (Label 1, Label 2) (Tag1 ... Tag n)
  • Point 2 (Label 3, Label 4) (Tag1 ... Tag n)

Putting both Lists to eager didn't work. So i tried my luck with a fetch join. It allowed me to fetch one list, but when i added the second list i get the known "cannot fetch multiple bags" error.

Can Hibernate handle two fetch joins in a query?

public class PointOfInterest
 @OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();

@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();

My fetch join:

SELECT DISTINCT p from PointOfInterest p 
        left join fetch p.labels 
        left join fetch p.tags WHERE p.figure = :figure

On startup the creation of my hibernate factory fails with:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
    at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
    at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
    ... 55 more
like image 443
mkuff Avatar asked Aug 24 '11 14:08

mkuff


1 Answers

The answer is: no. It can't handle it. That's what it says.

For value types (composite-element) it wouldn't even work, because you don't get the information what actually belongs to the same bag item.

Usually it doesn't even make sense. If you query a table and get 10 records in the starting table, 10 in the first bag and another 10 in the second bag, you'll retrieve 1000 records just to create these 30 objects in memory. Imagine the number of records when there would be 100 records in each table (hint: 1,000,000 instead of 300) and when you fetch join another bag (hint: 100,000,000 instead of 400) ...

By the way: join fetch may lead to strange effects and problems and should be avoided, except you exactly know what you are doing.

like image 88
Stefan Steinegger Avatar answered Nov 15 '22 04:11

Stefan Steinegger