开发者

nHibernate Many-To-Many mapping and Lazy loading

开发者 https://www.devze.com 2023-03-11 07:18 出处:网络
I am having a problem with a Many-to-Many association and the session in nHibernate in my Web Application.

I am having a problem with a Many-to-Many association and the session in nHibernate in my Web Application.

The object I am working with has always maintained it's connectio开发者_JAVA技巧n to the session though trips to and from the server. Never had a problem. Until now. I added a new, many-to-many, association to my class.

Here is that Many-To-Many mapping (names changed to make more sense):

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

When I run the code it works on the initial load. However subsequent calls to the server which access this object - the object is maintained in the web session - cause this collection to be broken and throw this error:

failed to lazily initialize a collection, no session or session was closed

Strange. I wondered if there is something about it being a many-to-many association which causes the issue? This many-to-many is added only to this class and not to the class on the other end of the mapping, the 'CategoryClass', as I don't need it there. The Object seems to be fine until I add this mapping.

Any Ideas?

ALSO: I tried simply checking if the object is no longer in the session. It Isn't. So I call: session.refresh(productClass) and everything gets updated correctly including my troublesome mapping. However. It's loads each item in the collection TWICE! the collection has twice as many items as there is in the database, each single items appearing twice. If I could get an answer to this problem that the prior one doesn't matter so much.

Please let me know if you need any additional informations. Cheers.


I'm assuming you're using the session-per-request pattern in a web application. Lazy loading requires that the session that was originally used to load the parent object is still open when it's child collection is accessed. You're creating a new session on every HTTP request, so objects stored in session state in the first request are detached objects in the second request. That's why you get the error and why the original object is not in the session on the second request.

To fix it, call ISession.Lock when accessing the object from session state.

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

That should fix your problem but a better approach may be to use NHibernate's second level cache ability instead of session state.

By the way, you probably don't want cascade="all-delete-orphan" in the many-to-many mapping. That would cause Category objects to be deleted when a Product is deleted.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号