【问题标题】:How do I manually open a hibernate session?如何手动打开休眠会话?
【发布时间】:2009-05-19 18:53:34
【问题描述】:

我有一个涉及 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,并且不存在 当前 休眠会话可以通过 OpenSessionInView 劫持。考虑到限制,解决这个问题的最佳方法是什么?我发现的唯一解决方案依赖于不合适的代码更改或现有会话,因此我认为我也许可以手动打开休眠会话。我该怎么做呢?或者,这个问题有更好的解决方案吗?

【问题讨论】:

  • 您使用的是 JPA 还是通用 Hibernate?你做了什么来尝试解决这个问题?

标签: java hibernate spring lazy-loading


【解决方案1】:

作为最佳实践,您需要使用会话工厂。这是 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 对象仅与一个线程相关联。如果我错了,请告诉我。

【讨论】:

  • 请在代码示例中包含导入的包,这样我们就无需猜测要导入哪些包。
【解决方案2】:

如果您可以获得对您配置的 SessionFactory 的引用,您应该可以在其上调用 openSession()。

【讨论】:

  • 我正在注入 sessionFactory,所以我会试试这个。
【解决方案3】:

您是否使用HibernateTemplateHibernateDaoSupport 来实现您的DAO?如果是这样,这就是您的对象断开连接的原因。但是,在这种情况下,您应该可以使用OpenSessionInViewInterceptor。你有没有做任何事情来验证你将无法使用拦截器?

另外,如果您选择打开一个新的Session,内存中的对象将不会与新的Session 关联。您需要将对象重新附加到会话才能使延迟加载工作。

【讨论】:

    【解决方案4】:

    如果您知道您的 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
    

    【讨论】:

      【解决方案5】:

      只需使用 会话会话 = new Configuration().configure().buildSessionFactory().getCurrentSession(); 或者 会话会话 = new Configuration().configure().buildSessionFactory().getOpenSession();

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 2014-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多