[hibernate-dev] Relations are not loaded when using Fetch Profiles
Vladimir Martinek
vm at sykora.cz
Thu Jun 2 08:45:05 EDT 2016
Fetch profiles fail to load certain relations because of invalid cycle
detection in MetamodelGraphWalker. Below is an example.
I have compared the behaviour of Fetch Profiles and standard EAGER
relations (EAGER does not suffer from this problem). The
MetamodelGraphWalker graph walker produces the same results, the SQL is
the same (missing relation).
With EAGER the relation is loaded in second pass, via
SessionImpl.internalLoad(). There it is decided what LoadType is used -
for eager it uses INTERNAL_LOAD_EAGER, for lazy INTERNAL_LOAD_LAZY. It
does not take into account the fetch profiles here!
The last place I can get hold of fetch profiles in in
AbstractLoadPlanBasedEntityLoader line 82. After that the fetch profile
information is lost, never making it anywhere near to
SessionImpl.internalLoad().
I would like to implement this, but to do that, I need someone to point
me in the right direction. Most of all I need answers to following
questions:
1) Is it right to assume the fetch profiles should be evaluated in
SessionImpl.internalLoad() and appropriate LoadType used when detected a
relation affected by a fetch profile?
2) If so, what is the intended way of getting the fetch profile
information to SessionImpl.internalLoad()?
Also, a colleague of mine attempted to implement FetchType.SELECT fetch
strategy and ended up with precisely the same problem. I believe solving
my issue would pave way for quick FetchType.SELECT implementation (which
we could also use on our project).
Thank you
Vladimir Martinek
Example:
Have 5 entities - Start, Via1, Via2, Mid and Finish with following
relations (all LAZY):
Start n:1 Via1 n:1 Mid n:1 Finish
Start n:1 Via2 n:1 Mid n:1 Finish
Now, trying to use Fetch Profiles to load Start entity and all of its
relations. I would expect Hibernate to execute following SQL select:
SELECT * FROM Start s
LEFT OUTER JOIN Via1 v1 (path Start-Via1)
LEFT OUTER JOIN Mid
JOIN Finish
LEFT OUTER JOIN Via2 (path Start-Via2)
LEFT OUTER JOIN Mid
JOIN Finish
Unfortunately, ii ompletely omits the second join from Mid to Finish,
what I am getting is:
SELECT * FROM Start s
LEFT OUTER JOIN Via1 v1 (path Start-Via1)
LEFT OUTER JOIN Mid
JOIN Finish
LEFT OUTER JOIN Via2 (path Start-Via2)
LEFT OUTER JOIN Mid
I dug deeper into this and found cycle detection in
MetamodelGraphWalker, line 144. Basically, when MetamodelGraphWalker
detects a relation that has already been visited, it considers it a
cycle. But in my case it is not a cycle - I just came to the same
relation twice using two different paths.
More information about the hibernate-dev
mailing list