Monday, January 23, 2012

NHibernate proxy of incorrect type exception: "PropertyAccessException Invalid Cast (check your mapping for property type mismatches)"

Are you facing this exception?

NHibernate.PropertyAccessException : Invalid Cast (check your mapping for property type mismatches); setter of MyEntity ----> System.InvalidCastException : Unable to cast object of type 'MyOtherEntityProxy' to type 'AnotherEntity'.

Looking on google, I saw that other programmers have this type of problem.

This article can help you if you are using Ninject and uNhAddIns.NinjectAdapters for entity injection in NHibernate.

If you are using the "NinjectAdapter" assembly, you need to bind the IProxyFactory interface to a class, for example to the default provided with NHibernate, DefaultProxyFactory, if is good for you.
My problem was the definition of this bind in a Ninject kernel module, copied from somewhere on the net or from a book, I can't remember.
   Bind<NHibernate.Proxy.IProxyFactory>()
      .To<NHibernate.Proxy.DefaultProxyFactory>()
      .InSingletonScope(); // <= here the problem


Declaring this bind in singleton scope is not good because the instance will be shared between NHibernate entities metadata classes: so you will get always the first ProxyFactory instance created and you will receive an error like the one above at runtime when you need a proxy classes of a type different from the first one created.

Was really a pain and take a lot of time to find out the problem as you can image, and the solution is to declare the bind InTransientScope(), of course.

   Bind<NHibernate.Proxy.IProxyFactory>()
      .To<NHibernate.Proxy.DefaultProxyFactory>()
      .InTransientScope(); // <= problem fixed

Here the documentation about the object scopes in Ninject.

Doing a similar mistake, you could have the same problem with another dependency injection library like Sprint.Net or CastleWindsor, of course.

Hope it helps :)