Marking a collection as stale

9 views
Skip to first unread message

Chris B

unread,
May 21, 2012, 5:00:31 PM5/21/12
to nhu...@googlegroups.com
I have an interesting scenario in an application that I am working on. Using the familiar analogy, my entities look something like this:

public class Customer
{
    public virtual ISet<Order> Orders { get; set; }
}

public class Order
{
   // ...
}

A Customer has a (potentially large, 250k or more) collection of Orders. Of course, these are not my real entities, these are just to give you an idea of their shape.

For this use case, I need to create a complete copy of the Customer, including the Orders.  To prevent NH from loading all of the Orders into memory and doing an app level copy, I am pulling an end-run around the session and using a SQL query to copy the Orders forward. This works like a charm.  However, things get tricky when I want to work with the new copy of the Customer. Since NH doesn't know what the SQL did, it thinks that the new Customer's Orders collection is empty.

I basically need a way to tell the session that I did some stuff behind its back and that the Orders collection is stale. These are the things I have tried so far:

1. Session.Refresh(newCustomer) - this works well for orders with a small number of orders, but for large numbers of Orders is incredibly slow since NH (sensibly) tries to refresh all of the data for the Customer and Orders.
2. Session.Evict(newCustomer) - I get a KeyNotFoundException here (after a few second delay) that I don't fully understand. I assume that somewhere in my object graph, an entity which is not owned by the session is being evicted, possibly because I have some types that are mapped as IUserTypes in there. Not sure on that though.
3. Session.Evict(newCustomer.Orders) - I was hoping this would cause just the Orders collection to get expired, but it actually seems to have no effect since the set is not actually owned by the session.
4. Using a new session - this works, but is easy to mess up.  This logic could end up getting duplicated across many parts of the application if we need to  copy any other entities with large collections in them. It also doesn't keep the persistence as transparent as I would like. However, if necessary, this may be a workable solution.
5. Session.Clear() - this also has no effect which makes sense because I am pretty sure clearing the Session really just means to expire the first level cache, and that is not the issue in this case.

Ideally, I would like to replace the Orders collection with an uninitialized proxy so that NH would go to the DB and pull back the orders on the next request. This would prevent me from needing to refresh the entire Customer object and allow me to only load the Orders if necessary. Something like session.MarkStale(customer.Orders) would be great.
Reply all
Reply to author
Forward
0 new messages