0

AMF Servlet 中正在发生一些肮脏的事情......

我调用了一个 DAO 方法,该方法用于通过从 java 到 flex 的远程对象检索没有任何子级的 DTO 列表:

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;
    }

这是 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>

关闭会话后出现此错误,因为当对象在 AMF Servlet 上反序列化时,Hibernate 尝试加载此类的所有子级,我可以通过保持会话打开来查看每个子级的查询。因此,有 2 个修复程序可以消除此错误,一个是设置lazy="false"一对多关系,第二个是让会话保持打开状态,直到 AMF 完成加载所有子项,但这不是我想要的。为什么我被迫加载每个孩子?

编辑:好的,我只是以一种丑陋的方式解决了这个问题......我对检索到的列表进行了克隆,所以当这个列表被反序列化时,它不会触发任何 Hibernate 查询。有没有办法告诉 LCDS 哪些集合被延迟加载?

4

2 回答 2

0

好的,我想我现在明白了。显然,当你在延迟加载的集合上执行 list.size() 时,休眠会加载所有子项,并且由于集合不为空,我最好的猜测是 AMF Servlet 检查集合是否为空,然后检查大小在某些时候为 0,触发集合的完整加载。所以快速解决方法是遍历每个引用以查找惰性集合并将它们设置为 null。

于 2013-01-19T06:00:57.817 回答
0

有没有办法告诉 LCDS 哪些集合被延迟加载?

从来没听说过。我认为您应该考虑实施“在视图中打开会话”模式——您的模式是一个合适的用例。

更新

根据OP提供的“答案”,我想指出可能有更好的延迟加载和size操作方法。Hibernate 支持额外的惰性集合,它只对数据库发出一条select count(...语句,而不是加载整个集合,如果你只需要获取它的大小。只需添加此注释:

@LazyCollection(LazyCollectionOption.EXTRA)

有关详细信息,请参阅http://www.frightanic.com/2010/11/21/extra-lazy-one-to-many-mapping-with-hibernate/

于 2013-01-17T19:53:20.120 回答