繁体   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