📅  最后修改于: 2023-12-03 15:33:20.591000             🧑  作者: Mango
这个异常通常发生在使用Hibernate进行对象关系映射(ORM)时。当我们在一个session中从数据库中获取到一个实体对象,并将其持久化到缓存中时,Hibernate会为该实体对象生成一个代理对象,并且只有在需要访问该实体属性时,才会从缓存中加载该实体对象。
但是当我们在session关闭之后,再次去访问该实体对象属性时,就会抛出上述的异常。这是因为此时代理对象已经找不到之前的session,无法从缓存中加载实体对象导致的。
通常解决这个问题的方法是在session未关闭时,通过方法Hibernate.initialize()
来强制初始化代理对象。也可以通过配置文件hibernate.cfg.xml
中添加<property name="hibernate.enable_lazy_load_no_trans">true</property>
来允许无session的Lazy Initialization。
示例代码:
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
User user = (User) session.get(User.class, 2407);
Hibernate.initialize(user); // 强制初始化代理对象
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
对于web应用程序,通常需要在web的filter中打开session并进行初始化,以确保在控制器中可以正常访问持久化对象,例如:
public class HibernateSessionRequestFilter implements Filter {
private SessionFactory sessionFactory;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
sessionFactory = HibernateUtil.getSessionAnnotationFactory();
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
Session session = null;
try {
session = sessionFactory.openSession();
Hibernate.initialize(yourEntity); // 强制初始化代理对象
filterChain.doFilter(servletRequest, servletResponse);
} catch (Exception e) {
if (session != null) {
session.getTransaction().rollback();
}
e.printStackTrace();
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
}
@Override
public void destroy() {
}
}
以上是解决org.hibernate.LazyInitializationException的方法。