The ConversationScope is good only for use cases where you have a
distinct beginning and end of a "conversation."  For instance, a
wizard with several screens, or a window responsible for displaying
and editing a single record.
It is not recommended for use in a "session per application" scenario.

I have not seen any documentation on the CoversationScope, but the
code is not that complex.  You should be able to get a pretty good
understanding by comparing the SessionScope class to
ConversationalScope and ScopeConversation.

My primary project is a WPF application that can't really be broken
into conversations.
I wrote a bit about my particular difficulties here:
http://groups.google.com/group/castle-project-users/browse_frm/thread/83b1a1d17a46fcec/a0fe6d9eb658bfa7?lnk=gst&q=Jasek#a0fe6d9eb658bfa7

I assume you are in a similar situation.
Keeping a session open for the lifetime of an application is generally
not a good idea, primarily because of the cache and the possibility of
a failed session.  Each session has it's own first level cache.  This
cache will store every entity that is pulled/pushed from/to the
database during the session lifetime.  Obviously this could be a
potentially serious memory leak.
Several situations can cause a session to fail (timeout, bad query,
etc).  Any entities associated with a session will be disconnected if
it fails.  This can cause odd behavior and serious bugs to come from
recoverable and relatively minor issues.

The fundamental problem is that ActiveRecord and NHibernate appear to
have been designed for web server applications, not desktop
applications.  While it is trivial to define a unit of work in most
web applications, it can be damn near impossible in a desktop app.
Unfortunately, I have not found any other framework that comes close
to AR's features and stability without the same issue.

In my code, I primarily work in a detached state.  I open a
SessionScope only when accessing the database, and close it when I am
done.  If I need to access a lazy collection, I re-attach the
ActiveRecord object to a newly opened Scope using this function:
public virtual T Reattach()
{
    if (!holder.ThreadScopeInfo.HasInitializedScope)
        throw new Exception("Cannot reattach if you are not within a
SessionScope.");
    holder.CreateSession(typeof(T)).Lock(this,
NHibernate.LockMode.None);
    return (T)this;
}

Also, since you are working with WPF, you might have noticed that lazy
objects can cause havoc with WPF bindings.  This property often fixes
this for me by unboxing the object from the lazy proxy:
public virtual BaseModel<T> Self { get { return this; } }

Both of these are in my BaseModel class:
public abstract class BaseModel<T> : ActiveRecordLinqBase<T> where T :
BaseModel<T>

This design structure has worked well for me so far, but you do have
to be careful.  Because you are running in a detached state,
ActiveRecord will not be able to automatically track and update all of
your active entities.  If you access the same record in different
parts of your code, you may run into issues with stale entities and
conflicting data.

As you have noticed, running detached can be a major pain when using
lazy entities.  To fix this, I have been working on a custom
ByteCode.  It should be in a future release of ActiveRecord.  If you
want to try it out now, I just posted instructions here:
http://groups.google.com/group/castle-project-users/browse_frm/thread/be987e3084dad707

I use these additions in my code now, so I believe they are relatively
stable.  These modifications will allow you to forget about
SessionScopes for a good portion of your code.  This is especially
handy in WPF when you wish to bind to something lazy.  You will only
need to open a Scope explicitly for performance reasons, if you need
to manage a transaction, or if you are using NHibernate Futures.
Having said that, I still end up opening Scopes frequently.  If you
are planning on hitting your database more than once or twice in a
block of code, wrapping it in a Scope will speed it up greatly.

The only problem I have run into so far has been when moving complex
entities from Scope to Scope.  You can get some odd exceptions when
the ByteCode tries to reattach various portions of your entity tree to
the new session.  But these have been rare, easy to detect, and only
require the insertion of an occasional Reattach() call.

-Dan

On Mar 30, 6:01 am, Christian Axelsson <[email protected]> wrote:
> I would appreciate getting that document. There are a lot of 404 links from 
> Google to it. Maybe it should be rewritten and uploaded on the new site 
> (together with documentation on the conversation API).
>
> I read through that thread and I see that in a recent thread Dan actually 
> have done some work on the issue.
>
> /Christian
>
>
>
> -----Original Message-----
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Nicholas Kilian
> Sent: den 30 mars 2011 11:42
> To: [email protected]
> Subject: RE: AR and a stale transaction
>
> The only thing I can find is a message thread between Dan and Markus 
> discussing 
> it.http://groups.google.com/group/castle-project-users/browse_thread/thr...
> 8e68ab10479c2/13a65a1b8890e371
>
> I have a hard copy of Markus's document on the Conversation pattern 
> somewhere, will try find it, scan it and send it through to you.
>
> Markus did say it was designed as 'Conversation per Form' rather than 
> 'Conversation per Application'. My approach when passing instances between 
> forms or controls, is to get their PK and re-load the entity from the 
> database using the new scope.
>
> Regards
> Nick
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of Christian Axelsson
> Sent: 30 March 2011 11:38 AM
> To: [email protected]
> Subject: RE: AR and a stale transaction
>
> Your guess is almost correct as I'm on WPF, but that probably doesn't matter.
>
> Can you point me to any documentation on the conversation stuff? I can't find 
> anything on the AR web site.
> I tried to initialize a ScopedConversation when I configure AR but without a 
> global session scope AR explodes as soon as I try to access a lazy loaded 
> property in my front-end code. And keeping a global ConversationalyScope will 
> probably be as bad as keeping a global SessionScope, right?
>
> /Christian
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of Nicholas Kilian
> Sent: den 30 mars 2011 10:50
> To: [email protected]
> Subject: RE: AR and a stale transaction
>
> I guess you're on winforms? Take a look at ConversationalScope and 
> ScopedConversation.
>
> There was an article on it somewhere, but I think it got lost in the move to 
> the new docs site.
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of Christian Axelsson
> Sent: 30 March 2011 10:42 AM
> To: [email protected]
> Subject: AR and a stale transaction
>
> Hello,
>
> I try to persist an entity to database using
>
>   myEntityRepository.Save(myEntity); // This will end up calling 
> ActiveRecordMediator.Save(entity);
>   SessionScope.Current.Flush();
>
> By configuring AR to show SQL in output window I see that the update hits 
> database but for some reason it isn't committed to DB. Investigating further 
> I see that I'm stuck with an open transaction meaning that the whole table is 
> locked until my session scope is disposed (upon application exist).
>
> Currently I create a session scope when AR is initialized and leave it there. 
> Wrapping the save statement inside a new TransactionScope "fixes" the problem 
> but I find that kind of ugly. Manually disposing the current session scope 
> and recreating it also works but that is quite ugly as well I think.
> It feels like using a "global" session scope like this isn't really the way 
> to go but if I don't create a session scope before starting to throw queries 
> at AR lazy loading breaks.
>
> Any hints on how to solve this?
>
> /Christian
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Castle Project Users" 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 
> athttp://groups.google.com/group/castle-project-users?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Castle Project Users" 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 
> athttp://groups.google.com/group/castle-project-users?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Castle Project Users" 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 
> athttp://groups.google.com/group/castle-project-users?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Castle Project Users" 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 
> athttp://groups.google.com/group/castle-project-users?hl=en.- Hide quoted 
> text -
>
> - Show quoted text -

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" 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/castle-project-users?hl=en.

Reply via email to