开发者

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)开发者_如何学C
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
    ... 55 more


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.


Instead of using Set, you can split the query and load the entities in different queries.
Eg

    From PointOfInterest p left join fetch p.labels WHERE p.figure = :figure
    From PointOfInterest p left join fetch p.tags WHERE p.figure = :figure            

Please refer the link


You can't have 2 1-n eager-joins (or HQL fetch-joins) in the same query.

If you join to a 1-n table and there are 10 rows matches, all the common columns on the non-N entities are duplicated for each row.

If it returns 10 rows, it would have to decide which 1-n caused the extra rows. Which, technically, it could based on the join keys - if the join keys are unique primary keys. But this exception indicates that hibernate cannot tell.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜