views:

240

answers:

1

I try to use NHibernate from IronPython. I have copied the NHibernate dependencies to my C:\Users\shamel\python\HelloPy\libs directory.

I have this IronPython code:

import sys
sys.path.append("C:\Users\shamel\python\HelloPy\libs") 

import clr
clr.AddReference("NHibernate")
clr.AddReference("LinFu.DynamicProxy")
clr.AddReference("NHibernate.ByteCode.LinFu")

from Entities.Entity import Customer 
from NHibernate.Cfg import Configuration

configuration = Configuration();
configuration.Configure("PocoLib.cfg.xml");
configuration.AddXmlFile("Customer.hbm.xml");
factory = configuration.BuildSessionFactory();

My entity classes are defined in Entity.py in the Entity package. That explains the from Entities.Entity import Customer.

Here is what my Customer.hbm.xml file look like

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="Entities"
               namespace="Entities">

<class name="Customer" lazy="false">
...
</class>

The program fails on the configuration.AddXmlFile("Customer.hbm.xml"); line:

configuration.AddXmlFile("Customer.hbm.xml");
StandardError: Could not compile the mapping document: Customer.hbm.xml
ERROR: Module: nhtests could not be imported.

I suppose NHibernate is not able to resolve the assembly and namespace specified in the hibernate-mapping header. (The problem is not that the xml file is not found; I tried with a name that does not exist and I get a different error)

Any help will be greatly appreciated.

Sly

EDIT: 27 Dec 2009: Here is the stack trace. I think it confirms that NHibernate is not able to find my types.

*** Outer ***
MappingException
persistent class Entities.Customer, Entities not found
at Microsoft.Scripting.Actions.Calls.MethodCandidate.Caller.CallWithInstance(Object[] args, Boolean& shouldOptimize)
at IronPython.Runtime.Types.BuiltinFunction.BuiltinMethodCaller`2.Call1(CallSite site, CodeContext context, TFuncType func, T0 arg0)
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at Microsoft.Scripting.Utils.InvokeHelper`6.Invoke(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4)
at Microsoft.Scripting.Utils.ReflectedCaller.Invoke(Object[] args)
at Microsoft.Scripting.Interpreter.CallInstruction.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
*** Inner ***
MappingException
persistent class Entities.Customer, Entities not found
at NHibernate.Cfg.XmlHbmBinding.Binder.ClassForFullNameChecked(String fullName, String errorMessage)
at NHibernate.Cfg.XmlHbmBinding.ClassBinder.BindClass(XmlNode node, IDecoratable classMapping, PersistentClass model, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(XmlNode node, HbmClass classSchema, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(XmlNode parentNode, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(XmlNode node)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
*** Inner Inner ***
FileNotFoundException
Could not load file or assembly 'Entities' or one of its dependencies. The system cannot find the file specified.
at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.Load(String assemblyString)
at NHibernate.Util.ReflectHelper.TypeFromAssembly(AssemblyQualifiedTypeName name, Boolean throwOnError)
at NHibernate.Util.ReflectHelper.ClassForName(String name)
at NHibernate.Cfg.XmlHbmBinding.Binder.ClassForFullNameChecked(String fullName, String errorMessage)

EDIT 29 Dec 2009 : Even after I solve the namespace/assembly name issue, I don't think Nhibernate will be able to save/load my Python entities. As far as a now understand, when a Python instance is passed to a statically typed library (such as NHibernate), that library does not see its members. So Nhibernate will not find any property on my type because those properties are not visible to statically typed libraries. In order for this to work, NHibernate would have to support DLR integration, possibly using the C# 4.0 Dynamic keyword. To be continued...

A: 

It is not possible to use NHibernate from IronPython on entities defines in IronPython.

Sly
didn't clrtype work? I want to know more!
Mauricio Scheffer
I never got the clrtype to work. But even if I got that part to work, the rest would not work because NHibernate will not be able to use reflection to find and invoke the members of my entities because they are defined in IronPhyton. If you believe this is not correct please give me more info and I might give it another try.
Sly
I have no idea, I just wanted to know more about your experiments :) I think this would make an great topic for a blog post, even if you didn't get it to work.
Mauricio Scheffer