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
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);
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");
Instead of root.join(...)
you can use root.fetch(...)
which returns Fetch<>
object.
but it can be used in similar manner. Fetch<>
is descendant of Join<>
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");
...