Search code examples
javajpalazy-loadingeager-loading

Eager query in a lazy relation?


I have an entity with lazy relations like this:

@Getter
@Entity
@Table(name = "entity")
@SequenceGenerator(name = "seq_entity", sequenceName = "seq_entity", allocationSize = 1)
@DynamicUpdate
public class Entity {

    @Id
    @Column(name = "id_entity")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_entity")
    private Long id;

    @Setter
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_relation1")
    private Relation1 relation1;

    @Setter
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_relation2")
    private Relation2 relation2;

    // ...
}

When I make a query to load the other relations I have to specify them like:

return jpaQuery() .select(qEntity) .distinct() .from(qEntity) .innerJoin(qEntity.relation1).fetchJoin() .leftJoin(qEntity.relation2).fetchJoin() .fetch();

But I want to load them without specify into left joins and inner joins for one query... There is a way to load all in eager mode for one query? Is it possible to desactivate the FetchType.LAZY for one query?

I am thinking in something like

return jpaQuery() .select(qEntity) .distinct() .from(qEntity) .fetchEager();


Solution

  • You can use entity graph for that. It will be something like this:

    EntityGraph<Post> entityGraph = entityManager.createEntityGraph(YourEntity.class);
    entityGraph.addAttributeNodes("relation1");
    entityGraph.addAttributeNodes("relation2");
    

    And in query

    TypedQuery<Post> typedQuery = entityManager.createQuery(criteriaQuery);
    typedQuery.setHint("javax.persistence.loadgraph", entityGraph);
    Post post = typedQuery.getSingleResult();
    

    This can be enclosed with named entity graph (over entity)

    @NamedEntityGraph(
      name = "entity-with-all-relations",
      attributeNodes = {
        @NamedAttributeNode("relation1"),
        @NamedAttributeNode("relation2"),
      },
    

    thus reused many times. To do that, you use EntityManager#getEntityGraph