嵌入对象

时间:2016-03-23 05:07:04

标签: hibernate hql eager-loading

我有一个嵌入了对象的类

public class A {
   @Embedded
   private B b;

   // getter setter
}

在B类中,我有一个集合,例如

@Embeddable
public class B {
    @OneToMany(fetch=FetchType.LAZY)
    @JoinColumn(name="A_ID")
    List<C> cList;
}

和C类

@Entity
public class C {
    // not important
}

现在我想使用HQL查询一个对象,并急切地检索C列表。我试过了

select a from A a join fetch a.b.c c

但我收到此错误Join fetch: “query specified join fetching, but the owner of the fetched association was not present in the select list”

我读了这个Join fetch: "query specified join fetching, but the owner of the fetched association was not present in the select list",似乎是因为我的集合存储在嵌入对象中。

当然我可以做循环并使用Hibernate.initialize但是当获取更多数据时性能会下降。

是否可以一次性在HQL中执行此操作?

2 个答案:

答案 0 :(得分:2)

可以使用HQL急切加载嵌入式集合。我相信你需要修改一下HQL。

我已经测试了以下实体:

注意:在您的实体名称中添加了,因为我已经拥有同名ABC的课程在我的工作空间中添加了@Id注释以及toString方法等。

@Entity
class MultiA {
    public MultiA() {}

    public MultiA(List<MultiC> cList) {
        this.b.cList = cList;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public int id;
    @Embedded

    public MultiB b = new MultiB();
    @Override
    public String toString() {
        return "MultiA [id=" + id + ", b=" + b + "]";
    }

}

@Embeddable
class MultiB {
    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="A_ID")
    List<MultiC> cList = new ArrayList<MultiC>();

    @Override
    public String toString() {
        return "MultiB [cList=" + cList + "]";
    }

}

@Entity
class MultiC {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public int id;

    @Override
    public String toString() {
        return "MultiC [id=" + id + "]";
    }
}

最后使用的HQL是:

session1.createQuery("select distinct a from MultiA a join fetch a.b.cList").list()

这导致使用join:

触发下面的单个SQL
Hibernate: select distinct multia0_.id as id1_0_0_, clist1_.id as id1_1_1_, clist1_.A_ID as A_ID2_1_0__, clist1_.id as id1_1_0__ from MultiA multia0_ inner join MultiC clist1_ on multia0_.id=clist1_.A_ID

并提供以下输出,该输出返回MultiA的2个实体以及填充的MutliC

[MultiA [id=1, b=MultiB [cList=[MultiC [id=1], MultiC [id=2], MultiC [id=3]]]], 
MultiA [id=2, b=MultiB [cList=[MultiC [id=6], MultiC [id=4], MultiC [id=5]]]]]

答案 1 :(得分:1)

尝试在HQL中删除c的别名,如下所示:

select a from A a join fetch a.b.c

仅当您需要在whereselect子句中直接使用别名时,以及需要对c类的属性进行某些连接时,才需要别名。< / p>