Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,270
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 194 words

I have run into some conceptual issues with using NHibernate with WCF. At the most basic level, I sought to duplicate the Session-Pre-Request functionality that I currently use for the web. This relies on the BeginRequest EndRequest events to create and close NHibernate's session.

Appernatly there is nothing in WCF that is similar to this, at least not globally. It has been suggested that I can use IDispatchMessegeInsepctor* to open/close the NHibernate session. This is good enough for the common case, althought it is still more work than I would like (you need to add the behavior to each service, instead of doing it globally).

One interesting thing that occured to me is using WCF PerSession services with NHibernate. Since NHibernate is now much more aggresive about release database connections, it make much more sense to use WCF PerSession while utilizing the Session Per Conversation pattern for NHibernate. This, however, I am not sure how to handle transperantly to the service...

* By the way, is someone else is strunk by how similar WCF is to the way Castle Windsor works?

time to read 14 min | 2748 words

A while ago I posted about the ability to map n tables to a single entity in the Entity Framework. I didn't like it then, and I quoted from the Hibernate documentation that discourage this behavior:

We consider it an essential element of good object model design that the object model be at least as granular as the relational model. If the original data modeller decided that certain columns should be split across two different tables, then there must have been some kind of conceptual justification for that. There is no reason not to also make that distinction in the object model.

I still believe that this statement is true, except... I just run into an issue with my model, I have a case where I am importing data from another database, and I need to add additional data to it. I could add additional columns to the primary table, but that would make the import process much more complex than I would like it to be. I would have liked to make it work by splitting the data by table, rather than by columns.

With that in mind, I headed to NHibernate's JIRA, and found this issue about the problem. Conveniently, a patch was supplied as well.

A big thanks for Karl Chu for making all the work of porting the functionality from Hibernate. I love Open Source.

At any rate, you can now map several tables into a single entity in NHibernate, you can get the full details here (the new tests), but let us walk through a simple one first.

(Image from clipboard).png 

Name and sex are defined in the Person table, but everything else is defined on the Address table, we map it like this:

<class name="Person">

       <id name="Id" column="person_id" unsaved-value="0">

              <generator class="native"/>

       </id>

 

       <property name="Name"/>

       <property name="Sex"/>

 

       <join table="address">

              <key column="address_id"/>

              <property name="Address"/>

              <property name="Zip"/>

              <property name="Country"/>

              <property name="HomePhone"/>

              <property name="BusinessPhone"/>

       </join>

</class>

Obviously address_id is a FK to person_id (not the best names for them, come to think about it). Trying to load a person would cause this SQL query (reformatted):

SELECT

     p.person_id,

     p.Name,

     p.Sex,

     a.Address,

     a.Zip,

     a.Country,

     a.HomePhone,

     a.BusinessPhone

FROM dbo.Person p inner join dbo.Address a

     on p.person_id=a.address_id

There is quite a bit more that it can do (optional joins, etc), and you can check it out at the tests.

Note: this is on NHibernate trunk, so it won't be in the 1.2 release, which is currently in feature-freeze.

time to read 1 min | 143 words

Andrew is asking about the JetBrains C# IDE, I did some research right now, and literally all information about it is dated to 2005. There is no official response saying this, but I guess that JetBrains decided that there just isn't a point in trying to compete with Microsoft in this area. I find it very sad, since by and large I am very unhappy with VS itself, and I have been continually impressed by what JetBrains' stuff enables me to do.

I would really like to see an IDE from JetBrains for .NET. It is a big undertaking, but I have faith in their abilities to make it work. JetBrains, please give us a reasonable IDE, I am so tired of fighting VS, I want an IDE to be my friend not a foe.

time to read 5 min | 912 words

In my current project, I need to talk to BizTalk, and have BizTalk talk to me. I usually don't like to work with things such as BizTalk and SSIS, because almost invariably, they make simple things more complex than they should be.

At any rate, the sceario is simply consuming web services, and having web services that BizTalk can call. I had two options to use here, I could use the usual ASMX web services, or I could use WCF. I did some testing with WCF, and it seemed fairly straight forward to use, but what made me decide to use it (beside the wish to try it out) was the logging support. It makes debugging so much easier when not only does it write everything to file, but it also provide a tool that allows easy browsing of messages and conversations.

At any rate, predictably, I run into problems. I had taken the test code for the web services that I needed to put so BizTalk can call me, and converted it from ASMX to BizTalk. Everything seemed to work fine, I would get the mesage, but I wouldn't get the values.

Consider this:

public class AddOrderLineConfirmMessage
{
   public string WhoAuthorized { get { .. } set { .. } }
   public string OrderId { get { .. } set { .. } }
   public string OrderLineId { get { .. } set { .. } }  
}

I am skipping the attributes here, I think that you get the mesage :-).

Well, I managed to get the message just fine, and the OrderId and the OrderLineId were filled with the correct values, but the WhoAuthorized field (which is the most important one here) was null.

Naturally, I blamed BizTalk for this, and called them to have it fixed. They swore up and down that they are sending the value is being sent from their end, and that the problem is on my side. Since I don't believe that my code can be flawed, I decided to prove them wrong, and took the sample code that used ASMX, and tried that.

That worked, not only did it work, but it also had the oh so important WhoAuthorized field. I then pulled the logs from the WCF service and saw that indeed, the message was something like:

<AddOrderLineConfirmation>
   <WhoAuthorized>foo</WhoAuthorized>
   <OrderId>1</OrderId>
   <OrderLineId>2</OrderLineId>
</AddOrderLineConfirmation>

At that point I was getting annoyed by the whole "WCF can't even work for my simple scenario" and decided that I would solve this issue if I had to write my own XML parser to do it. I began to dig into the WCF configuration options (a world of its own), and find out why it was ignoring the value that was clearly there.

I tried this, I tried that, and I couldn't figure it out. Until eventually I pulled out the WSDL and looked at it, trying to see if there was a namespace difference that could case it to ignore the value, or something of this order, but everything looked fine.

After quite a few of head banging, I finally noticed something odd. The fields in the WSDL were ordered alphabetically. So the WhoAuthorized field came last. That was when I knew that I had the issue solved.

The problem was with field orderring and versioning.

Basically, ASMX service would generate a message where the fields are ordered by their source code order (unless you explicitly specify otherwise). WCF, however, will order the fields by default according o the alphabet.

By chance, the OrderId and OrderLIneId were placed in the source code in an order that matched their alphabetical orderring. That meant that when WCF was parsing the message, it encountered WhoAuthorized field at the beginning of the message, and discarded it because it wasn't valid for the first field. It continued to discard fields until it riched the OrderId field, after which it found the OrderLineId field. Both of them matched the definition of the service message, so they were filled, but anything else turned out to be out of order and thus ignored.

The solution was to put Order=num in all the DataMember attributes, which let WCF know what is the expected orderring of the field in the document.

The lesson, always look one level down, and make sure that you are looking, not staring.

time to read 1 min | 156 words

Scott Bellware started it, and Sam Gentile continued, Windows is not usable out of the box for power users. Right now I quote a figure of about three days for me just to set up a new machine so I can start working, and there is going to be a period of reduced prodactivity when I get the machine the way I want it.

It is not just installing software, it is also setting up path variables, letting Windows know that I am not a dummy, bringing over shortcuts and extensions, etc.

Sometimes people don't realize why I hate moving machines, or work at their machine, even for a short while. I am sorry, but WinKey+R, N should bring Notepad2, and Ctrl+B will take me to the implementation of a method. I should see file extensions and typing Booish would give me a interpreter into the framework.

time to read 9 min | 1652 words

I recently found myself needing to handle a case where I had three drop down lists, and I needed to setup cascading relationship between those:

 ThreeDropDowns.png

Using the CascadingDropDown extender really make this a breeze, except that I had additional requirement, the benefits drop down should be filtered by both policy and insurance. So, when a policy is selected, all the matching insurance types are filled as well as all the matching benefits for the policy. When an insurance is selected, the benefits list should contains only the benefits for this insurance type.

At first I tried to simply setup a new extender from benefits to policies, that worked, until I selected a value from the insurance list, after which trying to unselect a value would leave me with a disabled drop down. After a bit of fumbling, I came up with this code, that runs on the onChanged client-side event on the Insurances drop down list:

function updateBenefitsDropDownIfDisabled()

{

    if($('<%=Insurances.ClientID %>').selectedIndex == 0)

    {

       setTimeout("updateBenefitsByPolicy();",1);

      }

}

The reason that I am using setTimeout here is that I want the updateBenefitsByPolicy to run after all the associated event hanlders for the event has run ( including the one that disabled it ). Here is how updateBenefitsByPolicy works:

function updateBenefitsByPolicy()

{

      var behaviors =  Sys.UI.Behavior.getBehaviors($('<%=Benefits.ClientID%>'));

      for(var i=0;i<behaviors.length;i++)

      {

            var behave = behaviors[i];

            if(behave._name == "CascadingDropDownBehavior" &&

                  behave._parentControlID == '<%=Policies.ClientID %>')

            {

                  behave._lastParentValues = null;

                  behave._clearItems();

                  var updating = new Option();

                  updating.text = '<asp:Literal runat="server" Text="<%$ Resources:App, Updating %>"/>';

                  addToDropDown(dropDown,updating);

                  behave._onParentChange(null,null);

            }

      }

}

It uses internal variabled from the CascadingDropDown behavior, so it is a hack, but it works. It cycles through the list of behaviors for this element, searching for a CascadingDropDown whose parent is the policies drop down, then it clear the cache (forces it to go back to the server) and manually force an update on the cascade behavior.

Not the most elegant code, but it works...

time to read 2 min | 270 words

D. Mark Lindell has a few questions about sclaing ORM:

  1. How can dynamic SQL ORMs deal with the fact that your database server (a.k.a SQL Server) can decide at any point that it is going to use an alternate query plan. A simple index HINT on the join syntax can fix this problem but how is my ORM going to handle this?
  2. How come there is no talk about scaling these ORMs. No, I'm not talking about scaling the database. A layer between the ORM and the database execution.

The answer to the first question is easy, you use index HINT when you need it. NHibernate makes it very easy to plug in your SQL (and I have several posts about - here is one) when the default approach is not sufficent, the 1.2 release goes beyond just leting you specify you SQL for queries, it lets you specify custom SQL for just about anything (Entity - CRUD, Collection - CRUD, etc).

I am not sure that I understand the second question at all, though.

time to read 44 min | 8606 words

There was some interest in extending the way NHibernate deals with the entities, and I have just commited those changes into the trunk. Notice that since NHibernate 1.2.0 is at feature freeze right now, this will not be in 1.2.0 RTM, but at a later version.

At any rate, let us see how we can extend NHibernate so it would offer automatic implementation for INotifyPropertyChanged. Some caveats: It works only for entities that have lazy loading enabled (the default for 1.2.0) which were retreived from NHibernate.

You can see the full test here, but let me go through the implementation. First here is the test case:

[Test]

public void CanImplementNotifyPropertyChanged()

{

       using (ISession s = OpenSession())

       {

              Blog blog = new Blog("blah");

              Assert.IsFalse(blog is INotifyPropertyChanged);

              s.Save(blog);

              s.Flush();

       }

 

       using (ISession s = OpenSession())

       {

              Blog blog = (Blog)s.Load(typeof(Blog), 1);

              INotifyPropertyChanged propertyChanged = (INotifyPropertyChanged)blog;

              string propChanged = null;

              propertyChanged.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)

              {

                     propChanged = e.PropertyName;

              };

 

              blog.BlogName = "foo";

              Assert.AreEqual("BlogName", propChanged);

       }

}

As you can see, when we create the entity manually, it does not implements INotifyPropertyChanged.  But when we load the object from NHibernate, not only does it implements INotifyProperyChanged, but it behaves correctly as well. They key is in extending the Proxy Factory that NHibernate uses for lazy loading.

We need to specify the proxy factory type that we would like to use:

protected override void BuildSessionFactory()

{

       cfg.SetProxyFactoryClass(typeof(DataBindingProxyFactory));

       base.BuildSessionFactory();

}

And now, let us see how the DataBindingProxyFactory works:

public class DataBindingProxyFactory : CastleProxyFactory

{

       public override INHibernateProxy GetProxy(object id, ISessionImplementor session)

       {

              try

              {

                     CastleLazyInitializer initializer = new DataBindingInterceptor(_persistentClass, id,

                                _getIdentifierMethod, _setIdentifierMethod, session);

 

                     object generatedProxy = null;

 

                     ArrayList list = new ArrayList(_interfaces);

                     list.Add(typeof(INotifyPropertyChanged));

                     System.Type[] interfaces = (System.Type[])list.ToArray(typeof(System.Type));

                     if (IsClassProxy)

                     {

                           generatedProxy = _proxyGenerator.CreateClassProxy(_persistentClass, interfaces, initializer, false);

                     }

                     else

                     {

                           generatedProxy = _proxyGenerator.CreateProxy(interfaces, initializer, new object());

                     }

 

                     initializer._constructed = true;

                     return (INHibernateProxy)generatedProxy;

              }

              catch (Exception e)

              {

                     log.Error("Creating a proxy instance failed", e);

                     throw new HibernateException("Creating a proxy instance failed", e);

              }

       }

}

Here we did two things, We specify a different interceptor, which inherits from the default interceptor, that handles lazy loading, and we specify that the proxy that NHibernate returns should also implement INotifyPropertyChanged. Now, we need to see how the DataBindingInteceptor works:

public class DataBindingInterceptor : CastleLazyInitializer

{

       private PropertyChangedEventHandler subscribers = delegate { };

 

       public DataBindingInterceptor(System.Type persistentClass, object id, 
               
MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, ISessionImplementor session)

              : base(persistentClass, id, getIdentifierMethod, setIdentifierMethod, session)

       {

       }

 

       public override object Intercept(IInvocation invocation, params object[] args)

       {

              if (invocation.Method.DeclaringType == typeof(INotifyPropertyChanged))

              {

                     PropertyChangedEventHandler propertyChangedEventHandler = (PropertyChangedEventHandler)args[0];

                     if (invocation.Method.Name.StartsWith("add_"))

                     {

                           subscribers += propertyChangedEventHandler;

                     }

                     else

                     {

                           subscribers -= propertyChangedEventHandler;

                     }

                     return null;

              }

              object result = base.Intercept(invocation, args);

              if (invocation.Method.Name.StartsWith("set_"))

              {

                     subscribers(this, new PropertyChangedEventArgs(invocation.Method.Name.Substring(4)));

              }

              return result;

       }

}

We extend CastleLazyInitializer, which handles the usual lazy loading related logic for NHibernate, and when we get a method, we check to see if it a call to a method from the INotifyPRopertyChanged interface. If it is, we handle the add/remove of the event subscriber. But that is not the interesting part.

The interesting part is that after we let the method be processed normally (which is what the call to base.Intercept() does, we check to see if this is a property setter, and raise the appropriate event if it does.

The client code for this is very natural, and it took about 70 lines of code to add this functionality.

time to read 1 min | 162 words

Some of the comments about my Lazy Load post included discussion about how to handle Lazy Load scenarios in this cases. The answer is simple, I don't. I don't handle this scenario because I don't like the idea of a client application going directly against my database. This puts too much responsability at the client end, and leaving the server as a dumb data container. This also means that users can now connect to the database, which I really don't like.

My default architecture for a smart client application is a client application that talks to a set of web services, where usually there is a one service per form, or per functionality. In those cases, I don't worry about the usual SOA stuff, those are WS dedicated to the app. The application can make calls to the WS, and those make it explicit that a boundary is being crossed.

 

time to read 3 min | 452 words

Frans responded to my post about Lazy Loading. He disagrees with the comparision between lazy loading and paging, because...

The difference is in the fact that the first (paging) goes through the same channels for every fetch of new data while the second (lazy loading) first uses the normal channel to fetch data and after that uses functionality 'under the hood' to get the additional data.

This thus means that the lazy loading functionality bypasses the logic you would otherwise use to obtain data.

That is actually depending on how you define the logic for obtaining the data. Usually lazy loading would occur inside an aggerate root, so I don't believe that there is that much logic that is involved in getting the data. In both cases, it is the OR/M that is invoked to load the data from the DB, and hook up the correct assoications.

Most OR/M would provide you with a way to hook into this mechanism. In NHibernate, you can use IInterceptor.OnLoad to execute logic whenever an object is loaded, regardless of how it is loaded. I don't see this as a problem.

I am curious about the definition of logic to get the data, by the way. About the only thing that I can think of is security, where you may not be allowed to see the entire graph, but lazy loading may enable that, if you got the object model wrong. This is more an issue of proper design than anything else, in my opinion. An aggregate root should be the object you secure, and not its children.

It's therefore of upmost importancy that you realize if your application is really suitable for lazy loading or not and if not, don't use it. A good O/R mapping solution always lets you do pre-fetching/eager loading of entity graphs without lazy loading.

No argument about here, although my approach would be the other way around. A good place to avoid lazy loading is in remoting scenarios, for the same reason you don't want to memory map a file on a network share and page it in.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...