Try fast search NHibernate

22 December 2008

Implementing Conversation per Business Transaction

In the previous post I talked about the theory behind the pattern. This post is about its implementation.

Introduction

If you read my blog you know how much I like “Program to an interface and not to an implementation”; this mean that first of all you will see interfaces instead of classes.
One of the targets of this implementation is maintain the same style of the others “Session Easier” of uNhAddIns; this mean:

The big picture

IConversation
IConversation
Is a representation of a “Persistence conversation” I showed in the previous post. In addition there are some events.
ConversationException
Is the base exception for “all” conversation implementations.
IConversationFactory
So far I “don’t know” which will be the real implementation of the “Persistence conversation” (may be ADO.NET, may be NHibernate); its factory is needed.
IConversationContainer
As I said, in a IM, we may have more than one conversation happening at the same time. This fact still true for “Persistence conversation”. For a winForm application it is pretty easy to understand because, in the same application (mean same Thread), the user may activate more than one independent business-transaction. In a WEB application it still true because the user may open more than one browser-tab, in the same browser instance sharing the same HttpSession, activating various independent business-transaction (or better he sure hope that each tab are working in a independent persistence context).
IConversationsContainerAccessor
In my application I need something to access to the ConversationContainer instance (a sort of a specific ServiceLocator for ConversationContainer implementation) especially if I want allow the use of a formal DI container.

The implementation

ConversationImpl1
AbstractConversation
Encapsulation of the behavior of a generic Persistence conversation. The implementation, basically, define that each conversation have an ID defined at the moment of its creation, implements the EqualityComparer based on the ID, implements the Disposable pattern and implements the events managements. The real hard work will be done in the five abstract methods: DoStart, DoPause, DoResume, DoEnd, DoAbort.
NhConversation
At the end, I have arrived to the Persistence Conversation implemented for NHibernate. The base behavior was described at the end of the previous post, what I would explain here is the role of the two injected fields: factoriesProvider, wrapper.
The factoriesProvider is an implementation of ISessionFactoryProvider that is the class responsible to provide all ISessionFactory needed by our application. In uNhAddIns you have two available implementations to work with one or more than one RDBMS, respectively SessionFactoryProvider and MultiSessionFactoryProvider. In the MultiSessionFactoryProvider you can inject an instance of IMultiFactoryConfigurator or use the default implementation.
The wrapper is an implementation of ISessionWrapper. The main target of a wrapped session is the interception of the Close and Dispose. In uNhAddIns the base implementation are doing something more: it are ensuring that you are working applying a best practice for session&transaction management. The implementation of ISessionWrapper is the responsible to wrap a session and recognize a wrapped instance. In uNhAddIns, so far, you have two available implementations using Castle.DynamicProxy2 and LinFu.DynamicProxy. Obviously you can write your own implementation without transaction protection.
NHibernate Conversation solved, now the implementation of the others interfaces to work with Conversation-per-Business-Transaction pattern.
ConversationImpl2
DefaultConversationFactory
Nothing special to say, its implementation is trivial.
AbstractConversationContainer
Encapsulation of the behavior of the conversation container. What I’m not defining here is which will be the real context where the container are running, that mean where all conversation will be stored and where will be stored the current conversation id. The Store of conversation is a Dictionary<string, IConversation> where the key is the ConversationId and the value is an instance of an started conversation.
ThreadLocalConversationContainer
This is the implementation of the ConversationContainer for a winForm, or WPF, application. As you can see the CurrentId and the Store are two ThreadStatic fields.
ThreadLocalConversationalSessionContext
As I said at the begin of this post the “story” end when I have an implementation of ICurrentSessionContext. The implementation, at this point, is trivial but the advantage of an implementation of ICurrentSessionContext is really big:
  • Your DAOs/Repositories are wired only with NHibernate and nothing more than its SessionFactory.
  • You can change the strategy of session-handling without change absolutely nothing in your DAOs/Repositories
To be clear, about the advantage of an implementation of ICurrentSessionContext, take a look on how may appear an implementation of a simple DAO
public class SillyDao : ISillyDao
{
private readonly ISessionFactory factory;

public SillyDao(ISessionFactory factory)
{
this.factory = factory;
}

public Silly Get(int id)
{
return factory.GetCurrentSession().Get<Silly>(id);
}

public IList<Silly> GetAll()
{
return factory.GetCurrentSession().CreateQuery("from Silly").List<Silly>();
}

public Silly MakePersistent(Silly entity)
{
factory.GetCurrentSession().SaveOrUpdate(entity);
return entity;
}

public void MakeTransient(Silly entity)
{
factory.GetCurrentSession().Delete(entity);
}
}

As you can see I’m using factory.GetCurrentSession() this mean that my DAOs don’t know who and how the session is provided; don’t know nothing about uNhAddIns, don’t know nothing about conversation management.

Conclusion

The next step, perhaps before a working example, will be “Aspect Conversation-per-BusinessTransaction” to have the “Full cream” working together. If you are inpatient you can see it by your self.


kick it on DotNetKicks.com


21 December 2008

Conversation-per-Business-Transaction

In this post I will intent to describe a “new” pattern for NHibernate session management.

The Story

This pattern born some years ago, with another name “session-per-UseCase”, when I looking for a pattern to manage nh-sessions in Win-Form applications. The first implementation was not so clear and, before make it public, I have continued looking for some, well described, existing pattern. Two or three moths ago I was involved in another WinForm application, using NHibernate as persistence-layer, and I have re-begun the search for a pattern for session-handling in a rich-client application. This time my exigencies was something different because what I really want is a pattern to manage the session in complex applications even in web. By “complex-application” I mean an application where business-transactions involving more than one request is the norm and not the exception (for example a ERP of a big company). Using our best friend, Google, I find some few words about a pattern, used in JAVA, named “session-per-application-transaction” but his implementation is not so clear and is wired to some JAVA-world feature… unusable for me.

Session handling

When you read something about NHibernate-session-management is because we want abstract/”aspect” NH-session’s stuff from the code are using it. In general, or I hope so, you are using the session in something like a DAO/Repository and, in a use-case, you are calling more than one DAO/Repository. Open a new session in each DAO/Repository is an anti-pattern called session-per-call (or very closer to it). What we are searching is something to manage the session in an high-layer but without wire that layer with NHibernate. In a WEB environment it is pretty easy because we can manage the session using an implementation of a IHttpModule, or in the HttpApplication, “intercepting” the request (two patterns mentioned here). In a winForm, or WPF, aplication it is not so clear where the abstraction have place. In this post I will use an “artifact” named Model to represent the “abstraction-point” (in my mind the Model is the business-object that are using DAOs/Repository and domain-entities); in an MVC based application, probably, the abstraction have place in the Controller.

The Conversation

Perhaps you have idea about what is a “business-transaction” in your application but, what mean “conversation” ?

To describe the conversation I have imagined a chat between two persons. A chat may Start, Pause, Resume, and End. By “End” I mean: the end with some formal conclusion. Not all chats are terminated with “some formal conclusion” so, an event like Abort is needed. Resuming, in a conversation we may use five actions: Start, Pause, Resume, End, Abort. When I’m working in my PC, in general, I have more than one started chat, with more than one person. In my IM client, each chat is identified by an open form. In each chat I’m chatting about one specific matter, that mean that each chat have a specific context.

Resuming my conversation have: Id and Context properties, Start, Pause, Resume, End, Abort actions.

Can I apply the same concept to a persistence-conversation ?

Let me try…

ConversationSequence

First of all I have tried it using pure ADO.NET. In the ADO.NET scenario the Start and Resume of the conversation open a DbConnection and begin a DbTransaction, the Pause commit the DbTransaction and close the DbConnection; the End open a DbConnection, begin a DbTransaction, execute all pending db actions register in the UoW, commit the DbTransaction, close DbConnection, Dispose the UoW (obviusly I don’t spent so much time writing a good implementation of a PersistenceLayer nor UoW).

The Conversation with NHibernate

In NHibernate we have a well know and well described pattern named long-session (aka session-per-conversation). The description of the pattern is available in NHiA. For brevity here is the picture (extracted from Hibernate site)

session_conversation

As you can see there are various similar concepts between the session-per-conversation and Conversation-per-Business-Transaction. In Conversation-per-Business-Transaction there is one main difference: the Conversation is not a conceptual abstract description of what are happening but it is an interface with its concrete implementation.

To better understand let me explain what happen in Conversation-per-Business-Transaction:

  • Context: one object of the conversation context is the session (or better all sessions of all sessionFactories we are managing in a multi-RDBMS application).
  • Start : open a new session and hold it in the conversation-context (FlushMode.Never).
  • Resume : begin a nh-transaction
  • Pause : commit the nh-active transaction
  • End : begin a nh-transaction, Flush the session, commit the transaction
  • Abort : Close the session without Flush it

These are the base concepts behind the pattern.

If you want see one implementation of the pattern, even using Castle.Windsor to solve AOP, you can download uNhAddIns. I hope to have the time to write something more about the actual implementation soon.


kick it on DotNetKicks.com

15 December 2008

Identity: The never ending story

How many times you heard us saying “don’t use identity POID generator!” ?
To understand it better you must move your mind to an application, or a use-case, where the pattern open-session-in-view (aka session-per-request) is not applicable.

The Unit of Work

The Unit of Work (UoW) is a pattern described by Martin Fowler. When you work with NHibernate the real implementation of the pattern is the NH-Session (more exactly in PersistentContext inside de session). The commit and rollback, described in the pattern, are respectively the session.Flush() and the session.Close() (the close mean when close the session without Flush it). As usual the pattern described by Fowler is short and very clear so an explication is unneeded; here I want put more emphasis in two phrases:
“You can change the database with each change to your object model, but this can lead to lots of very small database calls, which ends up being very slow.”
“A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.”
In addition, note, Fowler are talking about business transaction (repeat business-transaction).
In NHibernate, setting the FlushMode to FlushMode.Never (MANUAL in Hibernate), if you begin a NH-Transaction and commit it, but without a session.Flush, nothing happen in DB.

Analyze Session-per-conversation

SessionPerConversation
The session-per-conversation pattern is an example of a business transaction that spans multiple requests. As described by Fowler the nh-session (the real UoW) spans the whole business-transaction and in each request we are begin-commit a NH-Transaction. At the end of the conversation, inside a NH-Transaction, we will chose to Flush or Close the NH-session (mean commit or rollback the UoW).
In session-per-conversation we don’t want have a NH-Transaction (that, in this moment, mean a ADO.NET transaction) open for the whole conversation because not only is “impractical”, as said Fowler, but, in my opinion, it break the concept of ACID.

How to break all ?

If you want break the UoW pattern, and session-per-conversation pattern, you have a very easy way:use identity as your POID strategy.
The identity strategy mean :
  • change the database with each change to your object model (see the phrase above)
  • if you run a session.Save in the first request you will have a new record in the DB, and you can’t rollback this change without run an explicit Delete.
In addition I want say that using identity you are “disabling” the ADO-batcher NH’s feature for inserts.
You can continue using identity but you must know what you are loosing, and only you know what you are winning (I don’t know what you are winning using identity when you are working with a spectacular persistence layer as NHibernate is).

12 December 2008

WOW!

Si en mi “sucutrucho” logro hacer lo que hago, que pasaría con algo como esto ?

Me divorcio ? hmmmm me parece lo mas probable.

Artorius

A week ago I started a new project in uNhAddIns; the code-name is Artorius.

The base target of Artorius is the HQL-AST (perhaps is better to think about it as nHQL-AST).

The picture

ArtoriusStruct

The Story

The port of the string-AST-parser is an old task in NHibernate (perhaps one of my first occupation). Hibernate are using an old version of ANTLR Parser Generator and more than one year ago Ayende and I had tried the port of that code, in two different ways, but without a usable result. After that work I found GOLD and Diego Jancic (aka “The economist”) had begin a work to implement an string-AST-parser based on GOLD; unfortunately the work on OSS is hard to maintain and perhaps the state of NHibernate code-base, at that moment, was not ready to receive the new parser.

In uNhAddIns , after a request of my friend and after implement DetachedQuery, in a weekend born something like a game, named: DetachedDynQuery

The first time I think about Artorius was as an evolution of DetachedDynQuery; a real AST representation of an HQL query. I must admit that was a loooong thinking, without touch my keyboard, for various reason (the first is that now we have LINQ).

The Situation

To have a better idea about what nHQL-AST must support, I have begun the work from the string-AST-parser based on GOLD. The actual parser are passing the test available here (basically to test the grammar).

Browsing the code you can see that there are some other incomplete work but before start the real implementation of the nHQL-AST I prefer to complete the grammar. If you want navigate the BNF, of the actual grammar, you can download the HQL.htm file from here.

05 December 2008

The light

Yesterday I saw the light at the end of the tunnel.

The Oslo project.

Do you want avoid XML to map your domain ? Which language you want use to configure NH ? Why not English or Spanish or Italian ?

http://wm.microsoft.com/ms/msdn/oslo/mwindowexample.wmv

NHibernate have a lot of fireflies… the EntityMode.Xml are allowing something like this but using XML mappings.

Well…sorry it is incomparable.

The same base concept was provided by AjGenesis some years ago, but even if today AjGenesis are supporting text, instead XML, the MGrammar appear as a very powerful tool to create our DSL to generate all artifacts, including NHibernate mappings of course (I know… I know… AjGenesis is a project of “good soul”, behind MGrammar there is Microsoft).