1

我会用一个例子来解释我的问题。在我的 JSP 登录页面中,每个正确的登录都会放置一个名为“用户”的对象的实例,该实例保存用户登录到 HttpSession( session.setAttribute("user",userObject)) 的数据。该对象的创建方式是,检查该用户的用户名和密码以及一个实例(从 HibernateSession 中检索 User 对象的 'User')。
在另一个页面中,当我从 HttpSession 检索上述 set userObject 时,可以无错误地检索该对象。但是当它的方法被调用时,它给出了一个异常。org.hibernate.LazyInitializationException: could not initialize proxy - no Session 为什么我不能从 HttpSession 中获取那个 userObject,即使我已经把它放在前面了?

为什么 HttpSession 中存在一个空对象(实例变量没有值),即使该对象在添加到会话时早先具有值?

4

2 回答 2

2

如果User实体具有延迟获取的集合属性,则可能发生这种情况。size()然后,只有当调用者实际需要通过例如、等访问它时,集合才会实际填充来自 DB 的数据。这需要在与检索iterator()时相同的 Hibernate 会话中发生。User在一个设计合理的 web 应用程序中,Hibernate 会话的生命周期就是一个 HTTP 请求-响应。因此,如果访问集合属性发生在不同的 Hibernate 会话中(阅读:不同的 HTTP 请求),那么您将得到这个异常。

要解决此问题,您要么需要急切地获取集合属性,要么Hibernate#initialize()在检索User.

也可以看看:

于 2012-04-26T12:57:47.320 回答
1

这是延迟加载的问题。存储在不同数据库实体(例如子对象列表)中的元素不会直接与主实例(您的用户对象)一起加载,而是稍后在真正访问它们时加载。优点是,只有真正使用的对象才需要从数据库中加载。

为了通过延迟加载加载这些额外的对象,Hibernate 需要一个会话。这是最初用于加载主实例的会话。此实例绑定到会话。如果会话在此期间关闭,您会收到您收到的错误消息。例如,如果您按此顺序执行

userObject = session.load(...);
session.close();
userObject.getChildObjects(...); // or whatever the method fetching extra objects is called

然后你得到你的错误信息。

您可以采取哪些措施来避免此错误:例如

  • 不要关闭会话
  • 在子对象的类映射中禁用延迟加载
  • 在关闭会话之前调用userObject.getChildObjects(...);,即使您在那一刻不使用获取的对象。

将主用户对象存储在 HttpSession 中基本上不是问题,但您可能在对象存在的同时关闭了 Hibernate 会话。

于 2012-04-26T13:11:34.480 回答