Hibernate could not initialize proxy - no Session: LCDS provokes lazy load on all collections

StackOverflow https://stackoverflow.com/questions/14384756

  •  16-01-2022
  •  | 
  •  

Question

Some dirty business is happening in the AMF Servlet...

Im calling a DAO method that is supused to retrieve a list of DTO without any children through a remote object from java to flex:

public List<NivelesPlantillasDto> getList()throws HibernateException{
        logger.info("getList()");
        List<NivelesPlantillasDto> list = new ArrayList<NivelesPlantillasDto>();
        Session session = null;
        try{
            session = SessionFactory.getInstance().openSession();
            list=(List<NivelesPlantillasDto>)session.createQuery("from NivelesPlantillasDto").list();
        }catch(HibernateException HE){
            logger.info(HE.getMessage(),HE);
            if (session!=null && session.isConnected())
                session.close();
            throw HE;
        }
        if (session.isConnected())
            session.close();
        return list;
    }

And this is the hbm.xml

<hibernate-mapping>
    <class name="architecture.dto.NivelesPlantillasDto" table="nivelesplantillas">
        <id name="pkNivelPlantilla" type="int">
            <column name="PKNIVELPLANTILLA" />
            <generator class="identity" />
        </id>
        <property name="plantilla" type="java.lang.String">
            <column name="PLANTILLA" />
        </property>
        <set name="habilidadesList" table="habilidades" inverse="true" lazy="true">
            <key foreign-key="FKNIVELESPLANTILLAS" not-null="true">
                <column name="FKNIVELESPLANTILLAS" sql-type="int"/>
            </key>
            <one-to-many class="architecture.dto.HabilidadesDto"/>
        </set>
        <set name="nivelesList" table="niveles" inverse="true" cascade="merge,delete-orphan" order-by="indice" lazy="true">
            <key foreign-key="FKNIVELESPLANTILLAS" not-null="true">
                <column name="FKNIVELESPLANTILLAS" sql-type="int"/>
            </key>
            <one-to-many class="architecture.dto.NivelesDto"/>
        </set>
        <property name="activo" type="boolean">
            <column name="ACTIVO" />
        </property>
    </class>
</hibernate-mapping>

This error comes up after closing the session, because, Hibernate tries to load all the children of this class when the object is being deserialized on the AMF Servlet, I can see the query of every children by leaving the session open. So there are 2 fixes for this error to go away, one is to set lazy="false" in both one-to-many relations, and the second is leaving the session open until AMF finishes to load all the children, but that's not what I want. Why am I forced to load every child?

Edit: Ok, i just fixed this in an ugly way... I did a clone of the list retrieved, so when this one gets deserialized, it doesn't trigger any Hibernate query. Is there a way to tell LCDS wich collections are being lazy loaded?

Was it helpful?

Solution

Is there a way to tell LCDS wich collections are being lazy loaded?

Not that I know of. I think you should consider implementing the "Open Session in View" pattern - yours is an appropriate use case for that.

Update

Based on the "answer" provided by the OP I'd like to point that there may be a better approach to lazy loading and the size operation. Hibernate supports extra-lazy collections which only issue a select count(... statement against the database instead of loading the entire collection if all you need is to get the size of it. Just add this annotation:

@LazyCollection(LazyCollectionOption.EXTRA)

See http://www.frightanic.com/2010/11/21/extra-lazy-one-to-many-mapping-with-hibernate/ for details.

OTHER TIPS

OK, i think i got it now. So apparently, when u do a list.size() on a lazy loaded collection, hibernate loads all children, and since the collections are not null, my best guess is that the AMF Servlet checks if a collection is null and then if the size is 0 at some point, triggering a full load of the collection. So the quick fix was to iterate through every reference looking for lazy collections and setting them to null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top