Problem #1: You must close / dispose the session. Period. No exceptions. If not, you will eat up all available database connections and crash.
You should use session-per-request. There's a couple of ways to handle this. The best way, IMO, is to use a dependency injection framework like Ninject, Windsor, or StructureMap. If you don't understand dependency injection, put it on your list of things to learn by the end of the week, and then do this: Call sessionFactory.OpenSession() when the request starts, and session.Dispose() when the request ends. Store the session in HttpContext.items. You can also open and close the session with an MVC action filter. Problem #2: Don't do the micro-transaction anti-pattern. You're opening and closing transactions with every little call in to your repository. Transactions should surround the entire business transaction. I like to use an action filter for this, but there's a number of ways to do it. On Mon, Aug 16, 2010 at 11:47 AM, [email protected] < [email protected]> wrote: > It's an asp.net mvc app. Base repository is a generic in my > infrastrature dll, implementations are in persistence dll, and the > "unit of work" as you call it, is in the httppost handler action for > Forum/Edit/{id}. The configuration and session factory are initialized > in the application start event in Global.asax via a little static > utility class I wrote. Each repository asks that class for a session > (one per instantiation). Disposing? Not really doing that.. It was not > in any of the tutorials. I guess I could do it in a deconstructor. How > would that help? The incoming viewmodel has a category id, grabbed > from a dropdown list. Basically I do this: > > public actionresult Edit(ForumEditModel model) > { > > Category current = categoryRepository.SelectFromForumId(model.Id); > Forum forum = current.GetForumById(model.Id); > > // update forum properties and then > > Categoru destination = > categoryRepository.SelectById(model.CategoryId); > > if (current != destination) > { > destination.AddForum(forum); > categoryRepository.Update(destination); > } > else > { > categoryRepository.Update(current) > } > } > > It works accept for that masty refreshing thing. > > Now then, ,what are you suggestions at this point regarding unit of > work? > > On Aug 16, 12:31 pm, Jason Dentler <[email protected]> wrote: > > Yes. You have some strange ideas about unit of work. Let's start with the > > basics and work up from there. What type of application is this - web, > wpf, > > wcf? Where are you starting the session? Where are you disposing it? > > > > On Mon, Aug 16, 2010 at 9:54 AM, [email protected] < > > > > > > > > [email protected]> wrote: > > > Well, I'm at college at the moment, so I do not have the exact code, I > > > will post that when I get home, > > > > > In the meantime, here is what I can tell you. > > > > > public void Update(T entity) > > > { > > > > > using (ITransaction tx = Session,BeginTransaction()) > > > { > > > Session.Update(entity); > > > tx.Commit(); > > > > > // see comment below on this line > > > Session.Clear(); > > > > > } > > > > > } > > > > > ** I got the following code to work, but it requires the commented > > > line above so that subsequent selects do not show the entity as being > > > owned by two separate parents because of the NH caching. The db > > > changes work. > > > > > if (currentCategory != destinationCategory) > > > { > > > destinationCategory.AddForum(forum); > > > categoryRepository.Updaet(destination); > > > } > > > > > So let ne refine my original question to this instead: is there a > > > better way of refreshing things other than calling Clear()? > > > > > On Aug 16, 8:40 am, Jason Dentler <[email protected]> wrote: > > > > You need to perform the operation as a single unit of work. Don't > flush > > > the > > > > session after each little piece. > > > > > > For the future, we really need to see your NH code, not your > repository > > > > abstraction on top of NH. > > > > > > On Sun, Aug 15, 2010 at 11:06 PM, [email protected] < > > > > > > [email protected]> wrote: > > > > > I have a relatively simple application where my main aggregate > chain > > > > > is: Category -> Forum -> Thread -> Reply. > > > > > > > My aggregate root repository is CategoryRepository natually. > > > > > > > I have AllDeleteOrphan set in my HasManyConvention so I can perform > > > > > deletes like the following. > > > > > > > category.RemoveForum(forum); > > > > > categoryRepository.Update(category); > > > > > > > Without it, all that happens is the foreign key get's nulled out, > but > > > > > the record remains. With it set, it works like it should. However, > it > > > > > introduces a problem in another action where I need to move a forum > to > > > > > another category. This code will demonstrate. > > > > > > > if (currentCategory != destinationCategory) > > > > > { > > > > > > > // this seems to be needed so that the cache doesn't show the forum > in > > > > > both categories > > > > > currentCategory.RemoveForum(forum); > > > > > > > // THIS LINE CAUSES THE ERROR. by the time it completes, the forum > is > > > > > an orphan and is deleted. > > > > > categoryRepository.Update(currentCategory); > > > > > > > // now add it to the destination > > > > > destinationCategory.AddForum(forum); > > > > > > > // and save it > > > > > categoryRepository.Update(destinationCategory); > > > > > > > } > > > > > > > So the question is: what is the proper way to perform this > operation? > > > > > > > -- > > > > > You received this message because you are subscribed to the Google > > > Groups > > > > > "nhusers" group. > > > > > To post to this group, send email to [email protected]. > > > > > To unsubscribe from this group, send email to > > > > > [email protected]<nhusers%[email protected]> > <nhusers%[email protected]<nhusers%[email protected]> > > > > > <nhusers%[email protected]<nhusers%[email protected]> > <nhusers%252bunsubscr...@googlegroups.com> > > > > > > > > > . > > > > > For more options, visit this group at > > > > >http://groups.google.com/group/nhusers?hl=en.-Hide quoted text - > > > > > > - Show quoted text - > > > > > -- > > > You received this message because you are subscribed to the Google > Groups > > > "nhusers" group. > > > To post to this group, send email to [email protected]. > > > To unsubscribe from this group, send email to > > > [email protected]<nhusers%[email protected]> > <nhusers%[email protected]<nhusers%[email protected]> > > > > > . > > > For more options, visit this group at > > >http://groups.google.com/group/nhusers?hl=en.- Hide quoted text - > > > > - Show quoted text - > > -- > You received this message because you are subscribed to the Google Groups > "nhusers" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<nhusers%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/nhusers?hl=en. > > -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
