如何在单个查询中检索嵌套的JPA实体

时间:2011-07-15 09:13:41

标签: java optimization jpa annotations eclipselink

我正在尝试使用eclipselink JPA检索实体,并且正在寻找一种方法来减少运行以检索单个实体的查询数量。我相信我应该使用@JoinFetch注释来检索与主实体相同的查询中的子实体。这适用于单个级别的连接,但不适用于多个级别。

在下面的示例中,EntityA包含EntityB的集合,其中包含EntityC。当我检索EntityA时,我想要一个查询返回所有3组实体数据。实际上,它生成2个查询,1个加入EntityA和EntityB,然后是一个单独的查询加入EntityB和EntityC。

是否可以将其合并为一个查询?

class EntityA {
    @OneToMany(mappedBy = "entityALink", fetch = FetchType.EAGER)
    @JoinFetch
    private Collection<EntityB> entityBs;
}

class EntityB {
    @JoinColumn(name = "X", referencedColumnName = "Y")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private EntityA entityALink;

    @JoinColumn(name = "A", referencedColumnName = "B")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinFetch
    private EntityC entityCLink;
}

class EntityC {

    @Id
    @Basic(optional = false)
    @Column(name = "SomeColumn")
    private String someField
}

2 个答案:

答案 0 :(得分:0)

如果您需要减少查询次数,可以使用延迟初始化 - FetchType.LAZY而不是FetchType.EAGER - 这样jpa就会在需要时从数据库中获取数据。但是你必须记住,当实体与经理断开连接时,这不起作用。因此,如果您将此实体发送到序列化表单的其他服务器(例如,在多级应用程序中),则必须再次将此实体与管理器连接。如果您的应用程序在一台服务器上运行,那么您就没有此问题。

总结并不是您问题的确切答案,但可能有助于优化此代码。

您的确切答案问题: 您可以使用命名查询,但然后查询解析为sql本机查询,并且您不确定这是否正常工作。但也许您可以使用本机查询方法?

em.createNativeQuery("SELECT ... your queries") 

为此,请阅读使用@SqlResultSetMapping批注配置结果实体类...

答案 1 :(得分:0)

首先编写查询以获取EntityA。

EntityA entity = <your Query> ;

然后致电

Collection<EntityB> entityB = entity.getEntityBs();
for(EntityB eachB : entityB){

    EntityC entityCLink = eachB.getEntityCLink();
}

注意:创建setter&amp;每个实体都有吸气剂。