簡體   English   中英

如何手動打開hibernate會話?

[英]How do I manually open a hibernate session?

我有一個涉及spring和hibernate的相當大的項目。 現在,我正在將某些對象從休眠狀態和內存中支持出來,而且我遇到了一些障礙。 我有以下設置。

A類包含許多基元和B類.B包含基元和C類,它們之前是延遲加載的

現在我有了這個

服務電話1:
1.)創建A類對象
2.)得到B類的對象
3.)在A中設置B.
4.)將A添加到內存中

服務電話2:
1.)從記憶中獲得A.
2.)從A獲得B.
3.)從B獲得C.
4.)在C上運行

因為C是延遲加載的,它依賴於現有的休眠會話來懶惰地從B加載自身,至少我相信這是如此。 但是,現在我需要延遲加載而不修改DAO以返回ID,並且當前沒有 hibernate會話用於劫持OpenSessionInView。 考慮到局限性,解決這個問題的最佳方法是什么? 我發現的唯一解決方案依賴於不合適的代碼更改或現有會話,因此我認為我可以手動打開一個hibernate會話。 我該怎么做呢? 或者,這個問題有更好的解決方案嗎?

作為最佳實踐,您將需要使用會話工廠。 這是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的自動會話/事務管理。 一旦配置正確,將在后台處理會話。

編輯:
只需重新閱讀您的問題和您對ID的觀點。 我相信sessionfactory方法將適用於您的目的,除非您正在進行多線程應用程序。 這是因為,默認情況下,Hibernate會話和鏈接到該會話的ORM對象僅與一個線程相關聯。 如果我錯了,請告訴我。

如果您可以獲得對已配置的SessionFactory的引用,則應該只能在其上調用openSession()。

您使用HibernateTemplateHibernateDaoSupport來實現您的DAO嗎? 如果是這樣,這就是您的對象斷開連接的原因。 但是,在這種情況下,您應該能夠使用OpenSessionInViewInterceptor 你有沒有做過任何事情來驗證你將無法使用攔截器?

此外,如果您選擇打開新Session ,則內存中的對象將不會與新Session關聯。 您需要將對象重新連接到會話,以便延遲加載工作。

如果您知道您的B對象可能引用了它們的C,那么您應該以預取C的方式檢索B。 例如HQL

from B as b where b.id = :ID

from B as b left join fetch b.c where b.id = :ID

只需使用Session session = new Configuration()。configure()。buildSessionFactory()。getCurrentSession(); 或者Session session = new Configuration()。configure()。buildSessionFactory()。getOpenSession();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM