我用的是ssh整合,其中有两个类:Employee和Department
配置文件如下:
Employee.hbm.xml如下:
<hibernate-mapping>
<class name="com.hg.bean.Employee" table="tb_employee" lazy="true">
        <id name="emp_id" type="java.lang.Integer">
            <generator class="native"/>        
        </id>      
        <property name="emp_name" type="java.lang.String" length="25" not-null="true"/>   
        <property name="emp_tel" type="java.lang.String" length="20" not-null="true"/>  
        <many-to-one name="dep" column="emp_dep" lazy="false"/>
    </class>
</hibernate-mapping>Department.hbm.xml如下:<hibernate-mapping>
    <class name="com.hg.bean.Department" table="tb_department" lazy="true">
        <id name="dep_id" type="java.lang.Integer">
            <generator class="native"/>        
        </id>
        <property name="dep_name" type="java.lang.String" length="25" not-null="true"/>                    </class>
</hibernate-mapping>当我查询的时候,想使用延迟加载时,即将Employee.hbm.xml中的<many-to-one name="dep" column="emp_dep" lazy="false"/>改为lazy="proxy"时,总会出现异常(它有三个值:false,proxy,no-proxy),应该说除了设置为false时,不会出现异常,其余的两个值都会出现异常,查了一些资料,说还需要字节码加强,本人并不知道什么意思,也不知道错在哪里,各位高手请指教了,先谢谢了!

解决方案 »

  1.   

    确定在使用dep的时候session是否已经关闭?
    false表示不使用延迟加载机制,所以查询Employee的时候所对应的dep就会查出来,此时关闭session不会出错。但是设置为使用延迟加载时,查询Employee不会拿出相对应的dep,而是将dep的id缓存起来,当需要dep的其他属性(如name)时,再从缓存里取出id进行查询(即如果需要的依然是dep的id,hibernate只会从缓存里拿出该id,而不用去数据库拿),此时如果session关闭了,则会抛session已经关闭的异常。
    不知道楼主能否看懂?建议楼主复习一下hibernate的缓存机制。
      

  2.   

    谢谢这位大虾的指点,你的意思我明白,不过可能我没能把我的问题准确的表述出来吧,我的问题是:当lazy="false"时,即不适用Hibernate的延迟加载时,程序运行是没有任何的错误的,不过当lazy="proxy"
    即我想使用Hibernate的延迟加载机制时,总会如下报异常:
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    也就是我在使用Hibernate的延迟加载时总是出现错误,觉得上面的配置没有什么问题,所以还请大虾再帮帮忙!厚分重谢!!
      

  3.   

    这个问题就是当你延迟加载某些内容的时候session 已经关闭导致的。所谓延迟加载就是当你明确调用entity的某个属性的时候,hibernate再去帮你查询,如果这个时候session已经关闭,就查不到东西,报nosession.
    既然你用了spring 那就把hibenate 的session也交由spring管理,可以避免这个问题。
      

  4.   

    你的程序中是不是用employee调用Department(employee.getDep();),如果你设置了lazy=“proxy”,就会使employee延迟加载Department,所以你用employee.getDep()调用时会报no session
      

  5.   


    正如这位大虾说的,我在查询employee时,用的是employee.getDep().getDep_name(),我有点不明白:是不是只要设置了延迟加载,就一定会对要查询的属性进行延迟吗?另外,如果设置了lazy="proxy",就会使employee延迟加载Department,用employee.getDep()调用时会报no session,那么什么时候调用时不会出现错误呢,有点晕了。
      

  6.   

    延迟加载 在Session关闭之前调用。
    如果是BS项目的可用使用hibernate的openInViewFilter
      

  7.   

    说错了是Spring的OpenSessionInViewFilter帮定一个Session 使用同一个Session进行延迟加载
      

  8.   

    有两种方法:1.openInViewFilter,配置在WEB.XML中,这种配置的优点是:能让SPRING对没次的会话集中管理,缺点是:框架的耦合性高,不容易变相于其他模式的开发。2.使用最老的方式管理,自己写一个专门启动LAZY和关闭的注册对象,在里面动态LAZY所需要的对象,核心调用hibernate.initialize方法对对象进行LAZY加载,缺点:类生成比较多,优点:可移植性高,扩张突出。
      

  9.   

    Spring解决JPA延迟加载的问题  ,可以参照这里