[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