开发者

Hibernate Question on Sessions

I am writing a web application that allows a user to get an employee's personal information and edit it (email, phone, name, etc). When I deploy the application on the server, if I try edit the employee, I can occasionally get an error saying "Hibernate session is already closed." My code for talking to the dat开发者_如何学编程abase via hibernate is below:

/*
 * File: EmployeeMapper.java
 */

package org.hibernate.employee;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * This class represents the data mapper for an employee to the
 * database.
 */
public class EmployeeMapper {

    /**
     * Constructs an EmployeeMapper object.
     */
    public EmployeeMapper() {
    }

    /**
     * Finds an employee in the database by the username specified.
     * 
     * @param username the username to find
     * @return the employee if the username is in the database, null otherwise
     */
    public Employee findByUserName(String username) {
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Query q = session.createQuery("from Employee e where e.username='"
                    + username + "'");
            List results = q.list();

            for (Object o : results) {
                Employee e = (Employee) o;
                return e;
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
                   session.close();
            }
            return null;
    }

    /**
     * Updates the employee in the database by writing it to the database.
     * 
     * @param employee the employee to update in the database
     * @throws Exception 
     */
    public void updateEmployee(Employee employee) {
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.update(employee);
            session.getTransaction().commit();
        } catch(RuntimeException e){
            if(tx != null){
                tx.rollback();
            }
            throw e;
        } finally {
        session.close();
        }
    }

}

Does anyone have any suggestions for what I should do? If you need to post other classes or files to get more information on this program, please state what you need.


It's common to open a session for each view.


My guess is that you get that while processing your view (jsp/velocity/jsf). Read on the Open Session in View document which explains the problem thoroughly.


If you using Spring in your project try OpenSessionInViewInterceptor


When you get that error, you're not in that code.

For example, findByUserName return an object. That object has connections to other objects, that may not be initialized from the database.

  • While the Session is open, if you access that non-fetched data, database queries are triggered silently to fetch the data as you access it. This is the lazy mode.
  • Once you get out of the method, the Session is closed. Any attempt to access the lazy data will trigger the exception you mention.

In your example, while you think that only the above code talks to the database, there are probably outside accesses. Two solutions for your problem:

  • Use the Open-Session-In-View pattern explained in other answers. Note that they are several heavy drawbacks associated with it, so you have to carefully weight the options.
  • Ensure all the data you need is fetched before your business code delivers the entities to the Presentation layer. This is the approach that our last three applications have been using.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜