новая сессия - PullRequest
       7

новая сессия

0 голосов
/ 21 апреля 2009

Я использую Hibernate в NetBeans. Я использую класс hibernate util, который поставляется с плагином Hibernate для NetBeans, чтобы получить текущий сеанс. То есть я использую следующий код для получения моего текущего сеанса:

this.session = HibernateUtil.getSessionFactory().getCurrentSession();

Но когда я пытаюсь получить что-нибудь ленивое, выдается следующее сообщение:

org.hibernate.LazyInitializationException: failed to lazily initialize a course. 

Я использую 2 DAO. Одним из них является Abstract DAO, а вторым является CoutseDAO, который расширяет AbstractDAO. код выглядит следующим образом

public class AbstractDAO<T> {


    Session session = null;


    public AbstractDAO()
    {
      this.session = HibernateUtil.getSessionFactory().getCurrentSession();

   }

    public void createObject(T object)
    {
         Transaction tx = null;
        try
        {

            tx = session.beginTransaction();
            session.save(object);
            tx.commit();

        }
        catch (HibernateException e)
        {
            tx.rollback();
            throw new DataAccessLayerException(e);

        }
        finally
        {


        }
    }
    public  void updateObject(T object )
    {
         Transaction tx = null;
        try
        {

            tx = session.beginTransaction();
            session.update(object);
            tx.commit();

        }
        catch (HibernateException e)
        {
            tx.rollback();
            throw new DataAccessLayerException(e);

        }
        finally
        {


        }
    }

      public  void deleteObject(T object )
    {
         Transaction tx = null;
        try
        {

            tx = session.beginTransaction();
            session.delete(object);
            tx.commit();

        }
        catch (HibernateException e)
        {
            tx.rollback();
            throw new DataAccessLayerException(e);

        }
        finally
        {


        }
    }

}

второй класс выглядит следующим образом

public class CourseDAO extends AbstractDAO<Course>{

    public CourseDAO()
    {
        super();
    }

    public Course findByID(int cid){


        Course crc = null;
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Query q = session.createQuery("from Course  as course where course.cid = "+cid+" ");
            crc = (Course) q.uniqueResult();
            tx.commit();
        } 
        catch (HibernateException e)
        {
            e.printStackTrace();
            tx.rollback();
            throw new DataAccessLayerException(e);
        }

        finally
        {


        }
        return crc;
}


    public List<Course> findAll(){

        List lst = null;
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Query q = session.createQuery("from Course  ");
            lst =  q.list();
            tx.commit();
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
            tx.rollback();
            throw new DataAccessLayerException(e);
        }

        finally
        {



        }
        return (List<Course>)lst ;
}







}

Ответы [ 4 ]

0 голосов
/ 06 мая 2013

Это ужасное неправильное использование DAO для выполнения работы, для которой предназначен Hibernate.

  1. Границы транзакции не должны заканчиваться на границе метода DAO.
  2. вы не должны писать запросы от руки, где Hibernate может выполнить работу,
  3. findById () должен быть просто вызовом Session.load (Course.class, id).
  4. createObject( T object) неверно назван; это должно быть «сохранить».
  5. ловушка исключений также ошибочно размещена; это должно быть на границе Tx.

Все это совершенно неправильно, это абсолютный обман, все, что вы написали, неверно и не нужно. Ради Бога, вы пытаетесь написать JDBC и управление транзакциями, когда это уже сделано для вас.

Вот как должен выглядеть ваш код:

Session hb = sf.openSession();  // or wherever you get a Session from

// load by ID
Course course = (Course) hb.load( Course.class, id);

// list all courses
Criteria crit = hb.createCriteria( Course.class);
List<Course> allCourses = crit.list();

// create a new Course
Course newCourse = new Course("Hibernate 101");
hb.save( newCourse);

// delete the old one
hb.delete( course);

// flush & commit all changes, in a transaction.
Transaction tx = hb.beginTransaction();
/* hb.flush() */
tx.commit();

Избавьтесь от всех этого мусора DAO и используйте Hibernate напрямую, пока не узнаете, что делаете. Методы DAO / Business должны быть простыми и не пытаться выполнять управление транзакциями / или исключениями; они запускают в пределах транзакции.

0 голосов
/ 21 апреля 2009

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

getEm().find( MyClass.class, id );

По сути, всякий раз, когда вы вызываете метод в наших классах действий, вы должны делать это, чтобы убедиться, что объект не устарел в текущей сессии / транзакции.

Кроме того, исключение (даже если оно перехвачено!) Может закрыть текущий сеанс, вызывая ошибки LazyInitialization.

0 голосов
/ 21 апреля 2009

Вам нужно настроить диспетчер транзакций, чтобы hibernate мог выполнять запросы для отложенного извлечения в той же транзакции.

Сайт в спящем режиме, кажется, не работает, но у Google есть кеш

Чтобы включить стратегию с привязкой к потокам в конфигурации Hibernate:

set hibernate.transaction.factory_class to org.hibernate.transaction.JDBCTransactionFactory
set hibernate.current_session_context_class to thread

Существуют и другие варианты, такие как JPA, EJB или собственный.

Ваш код должен запускать транзакцию "вручную", если вы не работаете на сервере приложений или используете что-то еще, что обрабатывает транзакции для вас каким-либо другим способом.

try {
  factory.getCurrentSession().beginTransaction();

   // Do some work
  factory.getCurrentSession().load(...);
  factory.getCurrentSession().persist(...);

  factory.getCurrentSession().getTransaction().commit(); 
}
catch (RuntimeException e) {
    factory.getCurrentSession().getTransaction().rollback();
    throw e; 
}
0 голосов
/ 21 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...