When you call Repository.Save, you are notifying the session held by the repository to track that object and synchronize the changes to the database at the next flush. Until you flush the session, no changes are made to the database. The object does become part of the session cache though, and so will be returned by the Get(1).
When you run a query to populate a collection, the session queries the database to get the results, unless it has already cached those results. Since you have not updated the database yet, the Car you added to the session will not be part of the result set. (<-- Possibly incorrect) If I'm reading the documentation correctly, both query results and Save()ed entities should be added to the session (first-level) cache. That doesn't necessarily mean that the querystatement.List()
queries the cache after adding the DB results... I'm having a hard time wrapping my head around exactly what's going on.
As an aside, I believe you can set the session to autoflush but I'd have to check the documentation.
UPDATE:
I think I might see what's going on here. The default session FlushMode
is Auto
but Rhino's UnitOfWork.Start()
creates a session with a FlushMode
set to Commit
, which means the session will not auto-flush unless you explicitly call Flush()
or commit the transaction. With a FlushMode
of Auto
, NHibernate will (sometimes?) flush the session before querying to prevent stale data from being returned. If I'm right, your DB transaction looks something like:
SELECT * FROM Car
INSERT INTO Car (...) VALUES (...)
When it Auto flushes seems a bit ambiguous from the documentation/blogs I have read... the most common answer is that it with FlushMode = Auto
it flushes "sometimes" although guarantees that Session.Find
will never return stale data. Since NHibernate Linq actually just creates a Criteria query, it might not trigger the auto flush (maybe this has been fixed now... it's hard to know).
So it seems to me that in your case you want to flush after your save because you immediately want to retrieve the results of your save. In a smaller unit of work where you were only updating entities, a single Commit() would be fine. Maybe UnitOfWork.CurrentSession.FlushMode = FlushMode.Auto;
would do the trick but the fact that the UOW Factory explicitly sets the mode to Commit seems to be encouraging you to really think about your UOW boundaries.