Frage

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.

War es hilfreich?

Lösung

Don't use a debugger to test if an object is initialized. The debugger will call methods of your objects behind your back, to show the content of the object, and calling these methods will initialize the object.

Use Hibernate.isInitialized(question.getSection()) to test if the session is initialized.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top