I know there're a lot of questions about join vs join fetch.
The difference is explained as below:
A "fetch" join allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections.
However, when I have a Criteria or a HQL that uses an inner or outer join without fetching, I noticed that entities seem to be fully fetched (my hibernate mapping use FetchType.LAZY).
I only expected this when I write ' join fetch'.
So I don't see the difference in this case.
I must be missing something here.
Can someone help me to clarify this please?
UPDATE
StringBuilder hql = new StringBuilder();
hql.append("select question ")
.append("from User as user ")
.append("left join user.definition as definition ")
.append("left join definition.sections as section ")
.append("left join section.questions as question ")
.append("where user.id = :user");
Query query = getQuery(hql.toString());
query.setParameter("user.id", userId);
return query.list();
When I inspect the first item of the question List I get the following:
questions = {java.util.ArrayList@6756} size = 18
[0]={model.Question@6800}"model.Question@10f98160[]"
section = {Section$$_javassist_21@6873}"model.Section@7711057b[]"
handler = {org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@6890}
interfaces = {java.lang.Class[1]@6897}
constructed = true
persistentClass = {java.lang.Class@2708}"class model.Section"
getIdentifierMethod = null
setIdentifierMethod = null
overridesEquals = true
componentIdType = null
replacement = null
entityName = {java.lang.String@6898}"model.Section"
id = {java.lang.Long@6881}"1"
target = {model.Section@6899}"model.Section@7711057b[]"
name = {java.lang.String@6909}"General"
sequence = 1
textStart = {java.lang.String@6910}"Some value"
textEnd = null
sectionVersion = 1
status = {model.SectionStatus@6911}"ACTIVE"
definitions = {org.hibernate.collection.internal.PersistentSet@6912} size = 1
questions = {org.hibernate.collection.internal.PersistentSet@6913} size = 13
validFrom = {java.sql.Timestamp@6914}"2012-01-01 00:00:00.0"
validTo = {java.sql.Timestamp@6915}"2099-01-01 00:00:00.0"
active = false
uuid = {java.util.UUID@6916}"97277496-12ee-453d-9478-9fc4e1519c02"
id = {java.lang.Long@6881}"1"
version = {java.lang.Integer@6882}"1"
initialized = true
readOnly = false
unwrap = false
session = {org.hibernate.internal.SessionImpl@6900}"SessionImpl(PersistenceContext[entityKeys= [EntityKey[model.PossibleAnswer#57], EntityKey[model.PossibleAnswer#56], EntityKey[PossibleAnswer#59], E...readOnlyBeforeAttachedToSession = null sessionFactoryUuid = null specjLazyLoad = false
The Question class references to it's Section, in the stacktrace you can see that the Section is fully loaded although I didn't specify the 'join fetch' in my HQL.