Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Проблемы с Hibernate transaction.commit


Автор: STIM 15.12.2013, 06:32
Я использую Hibernate 4.2.4 и PostgreSQL 9.2. Проблемы с транзакциями. Сущность "Students" замаплена как многие-к-одному с сущностью "Groups" через аннотации. Когда я запускаю следующий кусок кода:
Код

StudentDAOImpl year = new StudentDAOImpl();
List<Students> stud = null;
List<Students> stud1 = null;
 
stud = year.getStudentsFromGroup(7);
stud1 = year.getStudentsFromGroup(7);
for (Students cat : stud) {
    System.out.println(cat.getName()+cat.getSurname());
    }
if( stud1.isEmpty()){ System.out.println("List is empty");}


Я получаю следующий неправильный результат:
Код

Bill Murrey
  Ivan Ivanov
  List is empty


Если я закомментирую это:
Код

session.getTransaction().commit();


Я получу правильный результат.Почему так? я же должен закоммитить транзакцию?
Код

@Override
public List<beans.Students> getStudentsFromGroup(Integer id)
        throws SQLException {
    Session session = null;
    List<Students>  students = null;
    try {
           session = HibernateUtil.currentSession();
           session.beginTransaction();
           students = session.createQuery ("from Students s where s.groups.groupid = :var1").setParameter("var1", id).list();   
           for (Students a : students) {
                Hibernate.initialize(a.getGroups());
                Hibernate.initialize(a.getTypeEducation());
            }
           session.getTransaction().commit();
         } catch (Exception e) {
             log.info("Проблемы с сессией! " + e.getMessage());
         } finally {
           if (session != null && session.isOpen()) {
               HibernateUtil.closeSession();
           }
         }
         return students;
}


Мой HibernateUtil класс
Код

public class HibernateUtil {
 private static final SessionFactory sessionFactory;
 @SuppressWarnings("rawtypes")
private static final ThreadLocal session = new ThreadLocal();
 
    static {
        try {
            Configuration configuration = new Configuration();
            configuration.configure();
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
                     configuration.getProperties()).buildServiceRegistry();
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
 
 @SuppressWarnings("unchecked")
public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
 }
 
 @SuppressWarnings("unchecked")
public static void closeSession() throws HibernateException {
        Session s = (Session) session.get();
        session.set(null);
        if (s != null) {
            s.close();
        }
        System.out.println("Сессия успешно закрыта! ");
 }

Автор: Samotnik 15.12.2013, 15:12
зачем этот блок?
Код

for (Students a : students) {
                Hibernate.initialize(a.getGroups());
                Hibernate.initialize(a.getTypeEducation());
 }

0.Открыл транзакцию
1.Выполнил запрос
2.Коммит транзакции
3. профит

Автор: STIM 15.12.2013, 15:16
Чтобы избавиться от ленивой инициализации. С коммитом транзакции беда, если его выполнить, то после этого ни один запрос с транзакциями не выполняется. Что делать?

Автор: Samotnik 15.12.2013, 16:37
Цитата(STIM @  15.12.2013,  15:16 Найти цитируемый пост)
после этого ни один запрос с транзакциями не выполняется

ошибка? какая?

Автор: STIM 15.12.2013, 17:06
В том то и дело что никакой ошибки. 
Как я уже в начале писал, выполняя этот код:

Код

StudentDAOImpl year = new StudentDAOImpl();
List<Students> stud = null;
List<Students> stud1 = null;
 
stud = year.getStudentsFromGroup(7);
stud1 = year.getStudentsFromGroup(7);
for (Students cat : stud) {
    System.out.println(cat.getName()+cat.getSurname());
    }
if( stud1.isEmpty()){ System.out.println("List is empty");}


Я получаю следующий неправильный результат:

Код

  Bill Murrey
  Ivan Ivanov
  List is empty


Хотя должен получить это.  Ведь вызываю один и тот же метод, с одним и тем же входным параметром. Если я закомментирую коммит, то  выводится правильно. 
Код

  Bill Murrey
  Ivan Ivanov
  Bill Murrey
  Ivan Ivanov


В чем проблема?

Автор: Samotnik 15.12.2013, 18:28
STIM, я предположу:
ты делаешь 
year.getStudentsFromGroup(7)
 в котором есть 
session = HibernateUtil.currentSession();
В котором сессия не открывается в случае, если она есть. Видимо, первый раз ты выгребаешь данные из сессии, а второй раз их там больше нет. Вообще метод currentSession() странный, обычно, перед каждой транзакцией нужно заново открывать сессию

Автор: STIM 15.12.2013, 18:52
Samotnik, спасибо большое! Действительно, там крылась ошибка, я неправильно управлял сессиями.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)