姬長信(Redy)

java – org.hibernate.LazyInitializationException:…


使用Hibernate和lazy = true模式从数据库加载对象列表时遇到了一些问题.
希望有人可以帮助我.

我在这里有一个名为UserAccount的简单类,如下所示:

public class UserAccount {
    long id;
    String username;
    List mailAccounts = new Vector();

    public UserAccount(){
        super();
    }

    public long getId(){
        return id;
    }

    public void setId(long id){
        this.id = id;
    }

    public String getUsername(){
        return username;
    }

    public void setUsername(String username){
        this.username = username;
    }

    public List getMailAccounts() {
        if (mailAccounts == null) {
            mailAccounts = new Vector();
        }
        return mailAccounts;
    }

    public void setMailAccounts(List mailAccounts) {
        this.mailAccounts = mailAccounts;
    }
}

我通过以下映射文件在Hibernate中映射此类:




    

        
            
            
        

        

        
            
            
        

    

如您所见,lazy在bag mapping元素中设置为“true”.

将数据保存到数据库工作正常:

加载也可以通过调用loadUserAccount(String username)来实现(参见下面的代码):

public class HibernateController implements DatabaseController {
    private Session                 session         = null;
    private final SessionFactory    sessionFactory  = buildSessionFactory();

    public HibernateController() {
        super();
    }

    private SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public UserAccount loadUserAccount(String username) throws FailedDatabaseOperationException {
        UserAccount account = null;
        Session session = null;
        Transaction transaction = null;
        try {
            session = getSession();
            transaction = session.beginTransaction();
            Query query = session.createQuery("FROM UserAccount WHERE username = :uname").setParameter("uname", username));
            account = (UserAccount) query.uniqueResult();
            transaction.commit();
        } catch (Exception e) {
            transaction.rollback();
            throw new FailedDatabaseOperationException(e);
        } finally {
            if (session.isOpen()) {
                // session.close();
            }
        }

        return account;
    }

    private Session getSession() {
        if (session == null){
            session = getSessionFactory().getCurrentSession();
        }
        return session;
    }
}

问题是:当我访问列表“mailAccounts”中的元素时,我得到以下异常:

org.hibernate.LazyInitializationException:
failed to lazily initialize a
collection of role:
test.account.UserAccount.mailAccounts,
no session or session was closed

我假设这个异常的原因是会话被关闭(不知道为什么和如何),因此Hibernate无法加载列表.
如您所见,我甚至从loadUserAccount()方法中删除了session.close()调用,但会话似乎仍然被关闭或被另一个实例替换.
如果我设置lazy = false,那么一切都很顺利,但这不是我想要的,因为我需要由于性能问题而“按需”加载数据的功能.

因此,如果在loadUserAccount(String username)方法终止后我无法确定我的会话是否仍然有效,那么具有该功能的重点是什么?如何解决这个问题?

谢谢你的帮助!

Ps:我是Hibernate的初学者,所以请原谅我的noobishness.

更新:这是我的hibernate config.cfg.xml




    
        com.mysql.jdbc.Driver
        foo
        jdbc:mysql://localhost:3306/mytable
        user
        org.hibernate.dialect.MySQLInnoDBDialect

        


        
        thread