Hibernate获取连接 - >无法取出多个行李

时间:2011-08-24 14:28:52

标签: hibernate join jpa-2.0 fetch

问题是我的实体中有两个包,我希望在我的jsf前端显示(后面的Spring,所以没有延迟加载)。所以我必须急切地获取它们以在这样的列表中显示信息:

  • 第1点(标签1,标签2)(标签1 ...标签n)
  • 第2点(标签3,标签4)(标签1 ...标签n)

将两个列表都置于热切之中并不起作用。所以我尝试了一下fetch join。它允许我获取一个列表,但是当我添加第二个列表时,我得到了已知的“无法获取多个包”错误。

Hibernate可以在查询中处理两个提取连接吗?

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

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

我的获取加入:

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

启动时,我的hibernate工厂的创建失败了:

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

3 个答案:

答案 0 :(得分:6)

答案是:不。它无法处理它。这就是它所说的。

对于值类型(复合元素),它甚至不起作用,因为你没有得到实际属于同一个包项目的信息。

通常它甚至没有意义。如果查询表并在起始表中获得10条记录,第一个包中有10条记录,第二个包中有10条记录,则只需在内存中创建这30个对象即可检索1000条记录。想象一下当每个表中有100条记录时的记录数(提示:1,000,000而不是300)以及当你获取加入另一个包时(提示:100,000,000而不是400)......

顺便说一句:加入获取可能会导致奇怪的效果和问题,应该避免,除非你完全知道自己在做什么。

答案 1 :(得分:1)

您可以拆分查询并在不同的查询中加载实体,而不是使用Set 例如

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

请参阅the link

答案 2 :(得分:0)

同一查询中不能有2个1-n eager-joins(或HQL fetch-joins)。

如果您加入一个1-n表,并且有10行匹配,则每行都将复制非N实体上的所有公共列。

如果返回10行,则必须确定是哪个1-n导致了额外的行。从技术上讲,如果连接键是唯一的主键,则可以基于连接键。但是此异常表明休眠状态无法识别。