4

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

4

5 回答 5

5

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

于 2009-05-19T19:19:40.747 回答
2

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

于 2009-05-19T19:08:51.127 回答
1

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

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

于 2009-05-19T19:45:10.163 回答
1

如果您知道您的 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
于 2009-05-20T17:31:24.423 回答
-3

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

于 2018-01-10T17:51:12.887 回答