nHibernate多对多映射和延迟加载

时间:2011-06-09 10:53:05

标签: nhibernate session nhibernate-mapping many-to-many lazy-loading

我在Web应用程序中遇到了多对多关联和nHibernate中的会话问题。

我正在使用的对象始终保持与会话的连接,但是往返于服务器。从来没有遇到过问题。到现在。我在班上添加了一个新的,多对多的关联。

这是多对多映射(名称改为更有意义):

 <bag name="ProductsToCategory" table="Tab_ProductsToCategory"" cascade="all-delete-orphan">
      <key column="ProductID" />
      <many-to-many class="CategoryClass" column="CategoryID" />
 </bag>

当我运行代码时,它适用于初始加载。但是后续调用访问该对象的服务器 - 该对象在Web会话中维护 - 导致此集合被破坏并抛出此错误:

  

懒得初始化a   收集,没有会话或会话   关闭

奇怪。我想知道是否存在导致问题的多对多关联?这个多对多只添加到这个类而不是映射另一端的类,即“CategoryClass”,因为我不需要它。 在添加此映射之前,对象似乎没问题。

任何想法?

ALSO:我只是尝试检查对象是否不在会话中。不是。所以我打电话给:session.refresh(productClass),一切都得到了正确的更新,包括我麻烦的映射。然而。它将加载TWICE中的每个项目!该集合的项目数量是数据库中的两倍,每个项目出现两次。如果我能得到这个问题的答案,那么前一个问题并不重要。

如果您需要任何其他信息,请与我们联系。干杯。

1 个答案:

答案 0 :(得分:5)

我假设您在Web应用程序中使用了每个请求的会话模式。延迟加载要求在访问父集合时,最初用于加载父对象的会话仍处于打开状态。您正在为每个HTTP请求创建一个新会话,因此在第一个请求中以会话状态存储的对象是第二个请求中的分离对象。这就是为什么你得到错误以及为什么原始对象不在第二次请求的会话中。

要解决此问题,请在从会话状态访问对象时调用ISession.Lock

var myProductClass = GetProductClassFromSession(); // whatever method you use to do this
session.Lock(myProductClass, LockMode.None);

这应该可以解决您的问题,但更好的方法可能是使用NHibernate的二级缓存能力而不是会话状态。

顺便说一句,您可能不希望在多对多映射中使用cascade="all-delete-orphan"。这将导致在删除产品时删除Category对象。