JPA entity graphs and Hibernate @Fetch(FetchMode.SELECT) mode


#1

As outlined in this discussion (https://hibernate.atlassian.net/browse/HHH-10485?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true) when using the EntityGraph class to query for data a JOIN is always used to construct the query to retrieve the data rather than a secondary select (the @Fetch annotation is ignored).

In the later part of the discussion the following question was raised but not answered

“Will we ever consider that if we annotate an association with @Fetch(FetchMode.SELECT) and the user wants to fetch it via Entity Graphs, then we should use secondary SELECTs rather than JOINs?”

Not allowing the @Fetch annotation to be considered limits the usefulness of using an EntityGraph in the case where there is more than one collection as discussed here Way to solve n+1 & cartesian product problem.

One of the pain points of using an ORM is often the need to translate from an Entity to DTO (and back). I think the addition of dynamic EntityGraphs with a combination of FetchMode.SUBSELECT and Hibernate filters
promises a 80-90% reduction in the need for a DTO layer in many use cases as the desired graph of entities can be simply specified and then populated at run time using the EntityGraph class only. However this requires a secondary select to populate the collections. Admittedly currently a Set could be used to house the collections but the underlying query will still produce a cartesian join.

Is anyone able to answer the question “Will we ever consider that if we annotate an association with @Fetch(FetchMode.SELECT) and the user wants to fetch it via Entity Graphs, then we should use secondary SELECTs rather than JOINs?” Other comments?

Thanks,

Tim


#2

If this is to be implemented, it has to be done in Hibernate 6 since the API changed considerably and it’s not worth trying to implement it in 2 ways.

Now, Hibernate has only 2 plans:

  • a default plan given by the entity mappings
  • a query-level plan given by the JOIN FETCH directive or FetchProfile or EntityGraph

Therefore, it’s not specified if the entity mapping annotation should influence the query-level plan so that a SELECT is done instead of a JOIN.

What you should do is to create a new Jira issue and maybe try to investigate how this can be done in Hibernate 6, and possible supply some prototype Pull Request for it.