简体   繁体   中英

How to retrieve nested JPA entities in a single query

I am trying to retrieve entities using eclipselink JPA and am looking for a way to reduce the number of queries run to retrieve a single entity. I believe I should be using the @JoinFetch annotation to retrieve sub-entities in the same query as the main entity. This works fine for a single level of join, but not for multiple levels.

In the example below, EntityA contains a collection of EntityB which contains an EntityC. When I retrieve EntityA, I want a single query to return all 3 sets of entity data. In reality it generates 2 queries, 1 joining EntityA and EntityB and then a separate query joining EntityB and EntityC.

Is it possible to combine this into one query?

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
}

First write a query to get EntityA.

EntityA entity = <your Query> ;

then call

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

    EntityC entityCLink = eachB.getEntityCLink();
}

Note : Create setter & getters in each entity.

If you need reduce number of queries, you may using lazy initialization - FetchType.LAZY instead of FetchType.EAGER - in this way jpa get data from databases when need. But you must remember, this is not working when entity is disconnected from manager. So if you send this entity to other servers in serialize the form (ex. in multi-level application) you must again connected this entity with manager. If you application runs in one server, then you don't have this problem.

Summing up is not the exact answer to your question, but maybe helpful for optimize this code.

Exact answer for you question: You may using named queries, but then query is parse to sql native query, and you don't sure that this working as you want. But maybe you may using native query method?

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

For this purpose, please read about using @SqlResultSetMapping annotation to configure result entity class...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM