我有一个涉及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是延迟加载的,所以它依赖于现有的hibernate会话从懒惰地从B加载自身,至少我相信这是如此。但是,现在,我需要延迟加载而不修改DAO以返回ID,并且存在无当前 hibernate会话以劫持OpenSessionInView。考虑到局限性,解决这个问题的最佳方法是什么?我发现的唯一解决方案依赖于不合适的代码更改或现有会话,因此我认为我可以手动打开一个hibernate会话。我该怎么做呢?或者,这个问题有更好的解决方案吗?
答案 0 :(得分: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对象仅与一个线程相关联。如果我错了,请告诉我。
答案 1 :(得分:2)
如果您可以获得对已配置的SessionFactory的引用,您应该只能在其上调用openSession()。
答案 2 :(得分:1)
您使用HibernateTemplate
和HibernateDaoSupport
来实施DAO吗?如果是这样,这就是您的对象断开连接的原因。但是,在这种情况下,您应该可以使用OpenSessionInViewInterceptor
。你有没有做过任何事情来验证你将无法使用拦截器?
此外,如果您选择打开新的Session
,内存中的对象将不会与新的Session
相关联。您需要将对象重新连接到会话,以便延迟加载工作。
答案 3 :(得分: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
答案 4 :(得分:-3)
简单地使用 Session session = new Configuration()。configure()。buildSessionFactory()。getCurrentSession(); 要么 Session session = new Configuration()。configure()。buildSessionFactory()。getOpenSession();