Спящий вопрос о сессиях - PullRequest
1 голос
/ 01 ноября 2009

Я пишу веб-приложение, которое позволяет пользователю получать личную информацию сотрудника и редактировать ее (электронная почта, телефон, имя и т. Д.). При развертывании приложения на сервере, если я пытаюсь отредактировать сотрудника, я иногда получаю сообщение об ошибке «Сессия Hibernate уже закрыта». Мой код для разговора с базой данных через Hibernate ниже:

/*
 * 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();
        }
    }

}

У кого-нибудь есть предложения, что мне делать? Если вам нужно опубликовать другие классы или файлы, чтобы получить больше информации об этой программе, укажите, что вам нужно.

Ответы [ 4 ]

1 голос
/ 01 ноября 2009

Если вы используете Spring в своем проекте, попробуйте OpenSessionInViewInterceptor

1 голос
/ 01 ноября 2009

Я предполагаю, что вы получаете это при обработке вашего представления (jsp / speed / jsf). Прочитайте документ Open Session in View , в котором подробно объясняется проблема.

1 голос
/ 01 ноября 2009

Когда вы получаете эту ошибку, вы не в том коде.

Например, findByUserName вернуть объект. Этот объект имеет связи с другими объектами, которые нельзя инициализировать из базы данных.

  • Когда сеанс открыт, если вы обращаетесь к этим не извлеченным данным, запросы к базе данных запускаются без вывода сообщений для извлечения данных по мере их доступа. Это ленивый режим .
  • После выхода из метода сессия закрывается. Любая попытка получить доступ к ленивым данным вызовет исключение, которое вы упомянули.

В вашем примере, хотя вы думаете, что только вышеприведенный код взаимодействует с базой данных, возможно, есть внешние доступы. Два решения для вашей проблемы:

  • Используйте шаблон Open-Session-In-View , описанный в других ответах. Обратите внимание, что с ним связано несколько серьезных недостатков, поэтому вам нужно тщательно взвесить варианты.
  • Убедитесь, что все необходимые данные извлекаются до того, как ваш бизнес-код доставит объекты на уровень презентации. Именно такой подход использовали наши последние три приложения.
1 голос
/ 01 ноября 2009
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...