Как открыть сеанс гибернации вручную? - PullRequest
3 голосов
/ 19 мая 2009

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

Класс A содержит несколько примитивов, а класс B. B содержит примитивы и класс C, который ранее был загруженным с отложенным доступом .

Теперь у меня есть это

Сервисный звонок 1:
1.) создать объект класса A
2.) получить объект класса B
3.) установить B в A
4.) добавить A в память

Сервисный звонок 2:
1.) получить А из памяти
2.) получить B от A
3.) получить C от B
4.) работать на C

Поскольку C загружается с отложенной загрузкой, он полагался на существующий сеанс гибернации, чтобы лениво загружать себя из B с помощью hibernate, по крайней мере, я считаю, что это так. Однако теперь мне нужно лениво загрузить без изменения DAO для возврата идентификатора, и существует нет текущего спящего режима для перехода в OpenSessionInView. Как лучше всего решить эту проблему, учитывая ограничения? Единственные решения, которые я нашел, основаны на неподходящем изменении кода или существующем сеансе, поэтому я думаю, что я мог бы, возможно, вручную открыть сеанс гибернации. Как бы я поступил так? В качестве альтернативы, есть ли лучшее решение этой проблемы?

Ответы [ 5 ]

5 голосов
/ 19 мая 2009

Лучше всего использовать фабрику сессий. Вот то, что генерирует Netbeans.

public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    private static final Configuration configuration = new Configuration().configure();

    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml) 
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Получив этот код, вы можете использовать этот код для транзакции

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
//Do something
session.getTransaction().commit();

Обратите внимание, что открытие транзакции откроет сеанс. Я полагаю, что в чистом Hibernate (в отличие от JPA) вам нужна транзакция, чтобы что-то делать, даже читать.

В конце программы вы хотите убедиться, что вы делаете это

HibernateUtil.getSessionFactory().close();

Для более изощренного решения вам может понадобиться автоматическое управление сессиями / транзакциями с помощью Spring или EJB. Который будет обрабатывать сеанс за сценой после того, как настроен правильно.

EDIT:
Просто перечитайте свой вопрос и свою точку зрения об идентификаторах. Я считаю, что сессионный подход будет работать для ваших целей, если только вы не создаете многопоточное приложение. Это связано с тем, что по умолчанию сеансы Hibernate и объекты ORM, связанные с этим сеансом, связаны только с одним потоком. Дайте мне знать, если я ошибаюсь по этому поводу.

2 голосов
/ 19 мая 2009

Если вы можете получить ссылку на ваш сконфигурированный SessionFactory, вы сможете просто вызвать openSession () для него.

1 голос
/ 20 мая 2009

Если вы знаете, что ваши объекты B могут ссылаться на свои C, вы должны извлекать B таким образом, чтобы предварительно извлечь C Например, HQL

from B as b where b.id = :ID

становится

from B as b left join fetch b.c where b.id = :ID
1 голос
/ 19 мая 2009

Используете ли вы HibernateTemplate и HibernateDaoSupport для реализации ваших DAO? Если так, то именно поэтому ваши объекты отключены. Но вы должны быть в состоянии использовать OpenSessionInViewInterceptor в этом случае. Вы сделали что-нибудь, чтобы проверить, что вы не сможете использовать перехватчик?

Кроме того, если вы решите открыть новый Session, объект в памяти не будет связан с новым Session. Чтобы ленивая загрузка работала, вам нужно снова присоединить объект к сеансу.

0 голосов
/ 10 января 2018

Просто используйте Session session = новая конфигурация (). Configure (). BuildSessionFactory (). GetCurrentSession (); Или же Сеанс сеанса = новая конфигурация (). Configure (). BuildSessionFactory (). GetOpenSession ();

...