Using the JPA Criteria API, can you do a fetch join that results in only one join?

后端 未结 3 2051
一向
一向 2020-11-30 03:52

Using JPA 2.0. It seems that by default (no explicit fetch), @OneToOne(fetch = FetchType.EAGER) fields are fetched in 1 + N queries, where N is the number of re

相关标签:
3条回答
  • 2020-11-30 04:24

    Starting with JPA 2.1 you can use dynamic entity graphs for this. Remove your fetch and specify an entity graph as follows:

    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<MyEntity> query = builder.createQuery(MyEntity.class);
    Root<MyEntity> root = query.from(MyEntity.class);
    Join<MyEntity, RelatedEntity> join = root.join("relatedEntity");
    query.select(root).where(builder.equal(join.get("id"), 3));
    EntityGraph<MyEntity> fetchGraph = entityManager.createEntityGraph(MyEntity.class);
    fetchGraph.addSubgraph("relatedEntity");
    entityManager.createQuery(query).setHint("javax.persistence.loadgraph", fetchGraph);
    
    0 讨论(0)
  • 2020-11-30 04:28

    Using root.fetch() on EclipseLink will create a SQL with INNER JOIN because have 3 types and the default is INNER.

    INNER,  LEFT,  RIGHT;
    

    The suggestion is to use CreateQuery.

    TypedQuery<T> typedQuery = entityManager.createQuery(query);
    

    EDIT: You can Cast the root to From like this:

    From<?, ?> join = (From<?, ?>) root.fetch("relatedEntity");
    
    0 讨论(0)
  • 2020-11-30 04:32

    Instead of root.join(...) you can use root.fetch(...) which returns Fetch<> object.

    Fetch<> is descendant of Join<> but it can be used in similar manner.

    You just need to cast Fetch<> to Join<> it should work for EclipseLink and Hibernate

    ...
    Join<MyEntity, RelatedEntity> join = (Join<MyEntity, RelatedEntity>)root.fetch("relatedEntity");
    ...
    
    0 讨论(0)
提交回复
热议问题