大家好,在下初学者,现在用struts2+hibernate做了一个简单的登录验证,但是出现问题,报的500错误,异常是
org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed在网上有的说,把hibernate里面的lazy="false"就行了,但是我的不行,而且就这一个表,也没有什么表关联。
还有一种方法是说在web.xml中加一段filter代码,我试过了也不行,我是是用的struts2和hibernate3,没有用spring
我的Action代码是:
package actions;import pojos.Users;import business.LoginService;
import business.impl.LoginServiceImpl;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport{
/**
 * 
 */
private static final long serialVersionUID = 1L;

private Users users; public Users getUsers() {
return users;
}
public void setUsers(Users users) {
this.users = users;
}
public String execute(){
LoginService login = new LoginServiceImpl();
Users usersresult = login.loadUsers(users.getUsername());
if(usersresult != null ){
if(usersresult.getPassword() == users.getPassword()){
}
return SUCCESS;
}
return INPUT;
}
}
实现类是:
package business.impl;import ooo.HibernateSessionFactory;import org.hibernate.Session;
import org.hibernate.Transaction;import pojos.Users;
import business.LoginService;
public class LoginServiceImpl implements LoginService{

public  Users loadUsers(String username) {
Session session = HibernateSessionFactory.currentSession();
Users users = null; try {
users = (Users) session.load(Users.class, username);
} catch (Exception e) {
} finally {
session.close();
}
return users;
}
}
在下是初学者,希望能得到各位的指点,谢谢大家了

解决方案 »

  1.   

    如果还是不行的话..发给我..我帮你调试下..呵呵~~~~邮箱:[email protected]
      

  2.   

    这个是配置文件:
    <?xml version="1.0" encoding='UTF-8'?>
    <!DOCTYPE hibernate-mapping PUBLIC
                                "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" ><hibernate-mapping package="xml">
        <class name="Users" table="Users" lazy="false">
            <id name="userid" column="userid" type="java.lang.Long" >
                <generator class="sequence">
                <param name="sequence">userid_seq</param>
                </generator>
            </id>
            <property name="username" column="username" type="java.lang.String"  not-null="true" length="50"/>
            <property name="password" column="password" type="java.lang.String"  not-null="true" length="50"/>
        </class>
    </hibernate-mapping>
    这个是hibernate.cfg.xml:
    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory> <property name="show_sql">true</property>
    <property name="dialect">org.hibernate.dialect.OracleDialect</property> 
    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:allengor</property> 
    <property name="connection.username">scott</property> 
    <property name="connection.password">tiger</property>
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
    <!-- 指定0到多个hbm.xml映射文件 -->
    <mapping resource="pojos/Mail.hbm.xml"/>
         <mapping resource="pojos/Users.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
      

  3.   

    load是根据主键来加载Users的,username不是其主键。
    你debug跟踪一下,看看调用实现层时加载的东西是否为空
      

  4.   


    把 login.jsp 登录页面的源码也贴一下
      

  5.   

    1,  先看 LoginServiceImpl 的 loadUsers(String username)。
         
         (1) Session session = HibernateSessionFactory.currentSession();
         (2) Users   users = (Users) session.load(Users.class, username);
         (3) session.close();
         (4) return users;    (1) 其中第一步表明你需要一个基于 threadLocal 的 Session。 目的是在一个完整的浏览器请求中一直使用一个 session。
        (2) 第二步没有什么问题
        (3)   没什么问题
        (4) 更没有什么问题了    问题的关键是这几个步骤结合起来就有问题了。
        当你 load 一个 user 时, 请注意这里 load 在hibernate内部的实现是通过代理机制的,就是说 hibernate 使用一个代理对象 A 代替了你查到的对象 user。
    假设  session.load(Users.class, username) 后,内存中有一个持久化对象 B,这个 B 对象是真实存在的, 而由于是load,所以 hibernate 有一个代理对象 A 引用了 B
        
        调用 session.close() 后,B 对象 就是游离状态。    而此时,你返回 user 这个 A 对象,供 struts 的 Action 处理,也就是 LoginAction.execute() 方法里面:
    Users usersresult = login.loadUsers(users.getUsername());
    if(usersresult != null )
    if(usersresult.getPassword() == users.getPassword()){
    }
    请注意 usersresult 这个东东永远不可能为null的。 而现在你却通过该  if(usersresult.getPassword() == users.getPassword()) ,使用代理对象的属性,在执行到这里的时候,代理对象就会真正的去调用内存中的那个真正的对象,而此时这个对象是不能被调用的。因为 B对象处于游离状态,所以会有楼主的错误出现。
    解决思路: 1,在你的 loadUsers 里面,不要使用 session.close(); 也就是说不要让B对象从持久状态转化成游离状态。
    这种情况我试过了,没有问题
    2,就是采用 open session in view, 在spring里面是有相关的filter,如果你不用 spring 那就自己写个呗,或者到网上找找例子看看。