您的位置:首页 > 其它

学习NHibernate时遇到的问题解决方法

2010-04-12 11:59 686 查看
一:
用spring.NET及Nhibernate时, 在项目处添加Spring_bean.xml这个文件,使用Spring.Context.IApplicationContext初始化时,例如:
xmlFiles[0] = "assembly://SpringNHibernateSample/OKEC.Sample/Spring_bean.xml";
IApplicationContext context = new XmlApplicationContext(xmlFiles); 执行此句出现如下错误:

System.TypeInitializationException: “Spring.Context.Support.AbstractApplicationContext”的类型初始值设定项引发异常。 ---> System.IO.FileNotFoundException:

未能加载文件或程序集“Common.Logging, Version=1.1.0.0, Culture=neutral, PublicKeyToken=65e474d141e25e07”或它的某一个依赖项。系统找不到指定的文件。
文件名:“Common.Logging, Version=1.1.0.0, Culture=neutral, PublicKeyToken=65e474d141e25e07”
在 Spring.Context.Support.AbstractApplicationContext..cctor()

注:出现此错误原因在于"未能加载文件或程序集Common.Logging",缺少Common.Logging.DLL这个DLL的引用.
解决方法是引用Common.Logging.DLL.

二:
解决了第一点的错误后,其它条件不变,它会提示以下出错信息:

System.Reflection.TargetInvocationException: 调用的目标发生了异常。 ---> System.IO.FileNotFoundException: Unable to load assembly [SpringNHibernateSample]
在 Spring.Core.IO.AssemblyResource..ctor(String resourceName)

注:很明显,它提示System.IO.FileNotFoundException,Unable to load assembly [SpringNHibernateSample],即找不到[SpringNHibernateSample]这个程序集.
问题就出现在xmlFiles[0] = "assembly://SpringNHibernateSample/OKEC.Sample/Spring_bean.xml";这一句的程序集,不应该为[SpringNHibernateSample],转到VS界面,项目-->

项目属性-->程序集名称,用此名称代替原来[SpringNHibernateSample]即可.我的程序集名称为PersistenceLayer,则:
xmlFiles[0] = "assembly://PersistenceLayer/OKEC.Sample/Spring_bean.xml";

三:
经过第二步后,可以发现,问题依然还有,但不是第二点的问题了,而是:
Spring.Objects.Factory.ObjectDefinitionStoreException: InputStream is null from Resource = [assembly [PersistenceLayer, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=null], resource [OKEC.Sample.Spring_bean.xml]]

注:明显,程序集正确,但还是没有找到Spring_bean.xml这个文件,不然转化成InputStream不可能为空.找资料发现:assembly定义的格式应该是:
assembly:<assemblyName>/<namespace>/<resourceName>.
所以再次更改:
xmlFiles[0] = "assembly://PersistenceLayer/PersistenceLayer/Spring_bean.xml";

四:
经过第三步更改后,出现以下错误:
Spring.Objects.Factory.ObjectDefinitionStoreException: InputStream is null from Resource = [assembly [PersistenceLayer, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=null], resource [PersistenceLayer.Spring_bean.xml]]

注:搞不懂什么原因.把xmlFiles[0] = "assembly://PersistenceLayer/PersistenceLayer/Spring_bean.xml";换成
xmlFiles[0] = "assembly://PersistenceLayer/PersistenceLayer/Spring_nhibernate.xml";
出现如下错误:
Spring.Objects.Factory.ObjectDefinitionStoreException: Error registering object with name 'PersistenceOperate' defined in 'assembly [PersistenceLayer,

Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Object class

[OKEC.Sample.NHibernate.NHibernateTest.UserCrossAuthen, SpringNHibernateSample] not found.
<object id="PersistenceOperate" type="OKEC.Sample.NHibernate.NHibernateTest.UserCrossAuthen, SpringNHibernateSample"

xmlns="http://www.springframework.net%22%3e%3cproperty/ name="SessionFactory" ref="SessionFactory" /></object> ---> System.TypeLoadException: Could not load type

from string value 'OKEC.Sample.NHibernate.NHibernateTest.UserCrossAuthen, SpringNHibernateSample'.

注:很明显,Object class [OKEC.Sample.NHibernate.NHibernateTest.UserCrossAuthen, SpringNHibernateSample] not found.说找不到这个类.然后转到Spring_nhibernate.xml

这个文件里看:

<object id="PersistenceOperate" type="OKEC.Sample.NHibernate.NHibernateTest.UserCrossAuthen, SpringNHibernateSample">
<property name="SessionFactory" ref="SessionFactory"/>
</object>

原来type=""这句,不能随意定的.上面定成这样,它找不到UserCrossAuthen这个类啊.
改成:<object id="PersistenceOperate" type="PersistenceLayer.UserCrossAuthen, PersistenceLayer">
<property name="SessionFactory" ref="SessionFactory"/>
</object>

又出现如下错误:
五:
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'DbProvider' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Initialization of object failed : 未能加载文件或程序集

“antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07”或它的某一个依赖项。系统找不到指定的文件。 --->

System.IO.FileNotFoundException: 未能加载文件或程序集“antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07”或它的某一个依赖项。

系统找不到指定的文件。
文件名:“antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07”

注:根据上面第一点的经验.应该引用antlr.runtime.DLL.引用这个DLL后:
出现:
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'SessionFactory' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Initialization of object failed : “NHibernate.Cfg.Configuration

”的类型初始值设定项引发异常。 ---> System.TypeInitializationException: “NHibernate.Cfg.Configuration”的类型初始值设定项引发异常。 --->

System.IO.FileNotFoundException: 未能加载文件或程序集“log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905”或它的某一个依赖项。系统找

不到指定的文件。
文件名:“log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905” ---> System.IO.FileNotFoundException: 未能加载文件或程序集“log4net,

Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905”或它的某一个依赖项。系统找不到指定的文件。
文件名:“log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905”

六:
以下的提示:加上log4net.DLL的引用.
出现如下错误:
Initialization of object failed : “NHibernate.Cfg.Configuration”的类型初始值设定项引发异常。 ---> System.TypeInitializationException:

“NHibernate.Cfg.Configuration”的类型初始值设定项引发异常。 --->

解决方法: 加上
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'SessionFactory' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Initialization of object failed : Could not add assembly named:

SpringNhibernateSample ---> NHibernate.MappingException: Could not add assembly named: SpringNhibernateSample ---> System.IO.FileNotFoundException: 未能加载

文件或程序集“SpringNhibernateSample”或它的某一个依赖项。系统找不到指定的文件。

七:
它提示:Could not add assembly named: SpringNhibernateSample ,找不到SpringNhibernateSample,转到Spring_nhibernate.xml,把
SpringNhibernateSample改成PersistenceLayer.

然后出现如下错误:
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'SessionFactory' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Initialization of object failed : 未能加载文件或程序集

“Iesi.Collections, Version=1.0.0.1, Culture=neutral, PublicKeyToken=154fdcb44c4484fc”或它的某一个依赖项。系统找不到指定的文件。 --->

System.IO.FileNotFoundException: 未能加载文件或程序集“Iesi.Collections, Version=1.0.0.1, Culture=neutral, PublicKeyToken=154fdcb44c4484fc”或它的某一个依赖

项。系统找不到指定的文件。

八:第七点的提示明确:少了Iesi.Collections这个DLL.加上.然后出现如下错误:

Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'PersistenceOperate' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Error setting property values: 'SessionFactory' node cannot be

resolved for the specified root context. ---> Spring.Objects.InvalidPropertyException: 'SessionFactory' node cannot be resolved for the specified root

context.
在 Spring.Objects.ObjectWrapper.SetPropertyValues(IPropertyValues propertyValues, Boolean ignoreUnknown)

注:哈哈,离正确越来越近了.根据经验,这个应该是数据库字段名与类名定义不一样造成.

九:
第八点没能解决
把xmlFiles[0] = "assembly://PersistenceLayer/PersistenceLayer/Spring_nhibernate.xml";换成xmlFiles[0] =

"assembly://PersistenceLayer/PersistenceLayer/Spring_bean.xml";出现第三步改完后的错误:

Spring.Objects.Factory.ObjectDefinitionStoreException: InputStream is null from Resource = [assembly [PersistenceLayer, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=null], resource [PersistenceLayer.Spring_bean.xml]]
在 Spring.Objects.Factory.Xml.XmlObjectDefinitionReader.LoadObjectDefinitions(IResource resource)

查询资料发现,是没有把Spring_bean.xml这个文件的属性的"生成操作"这一项改为"嵌入的资源",改成"嵌入的资源"后,第三点及第九点的问题解决,程序运行OK.

十:
现在继续第八点的错误:
在 Spring.Objects.Factory.ObjectCreationException 中第一次偶然出现的“Spring.Core.dll”类型的异常
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'PersistenceOperate' defined in 'assembly [PersistenceLayer, Version=1.0.0.0,

Culture=neutral, PublicKeyToken=null], resource [PersistenceLayer.Spring_nhibernate.xml]' : Error setting property values: 'SessionFactory' node cannot be

resolved for the specified root context. ---> Spring.Objects.InvalidPropertyException: 'SessionFactory' node cannot be resolved for the specified root

context.

注:仔细对比下载的DEMO的pring_nhibernate.xml文件与自己定义的pring_nhibernate.xml文件,发现这里有出入:

DEMO的:
<!-- 以下是业务相关的 -->
<object id="UserDao" type="OKEC.Sample.NHibernate.NHibernateTest.UserDao, SpringNHibernateSample">
<property name="SessionFactory" ref="SessionFactory"/>
</object>

自己定义的:
<!-- 以下是业务相关的 -->
<object id="PersistenceOperate" type="PersistenceLayer.UserCrossAuthen, PersistenceLayer">
<property name="SessionFactory" ref="SessionFactory"/>
</object>

发现type这里,PersistenceLayer.UserCrossAuthen这句有错误,定义PersistenceOperate这个对象,它是对应PersistenceOperate这个类的.而不是UserCrossAuthen这个类,所以出

错了,改为:
<!-- 以下是业务相关的 -->
<object id="PersistenceOperate" type="PersistenceLayer.PersistenceOperate, PersistenceLayer">
<property name="SessionFactory" ref="SessionFactory"/>
</object>

结果:通过context = new XmlApplicationContext(xmlFiles);这句执行没出错了.

十一:
接着执行HibernateTemplate.Get(typeof(UserCrossAuthen),ID);这一句,出现错误:
Unknown entity class:PersistenceLayer.UserCrossAuthen

原因在于没有找到UserCrossAuthen这个类,应该是映射的问题.后面发现,是没有把UserCrossAuthen.hbm.xml这个文件属性设置为"嵌入的资源".把它设置后.就不会提示这个错误了

.

十二:
经十一点后,提示"'Errors' node cannot be resolved for the specified root context."
解决方法:这个错误在第八第十点都有,所以,有可能是XML文件里定义的问题,也可能是其它地方的问题,比如说这次,就是数据库文件没有找到的问题,因为我建了两个工程,这个持久

层是单独的工程,是在其它工程调用这个DLL,我把数据库文件放在持久层工程处,它就找不到了,应该放到调用它的工程目录下.因为数据库定义成

provider=Microsoft.Jet.OLEDB.4.0;data source=.\\WareHouse.mdb;Jet OLEDB:Database Password=;

十三:
System.ArgumentException: identifier type mismatch
参数名: id
这个问题,是 HibernateTemplate.Get(typeof(UserCrossAuthen), ID)这一句出错的,原因在于ID这个参数,虽然是object类型,但是传进去的参数,必须与数据库定义的参数一样,比

如数据库定义的ID为整形,而传的参数是"1"这样的字符串形,它也不会强制转换.以至发生错误.把它改成1就行了.

十四:
解决修改数据的问题:只对对象的部分参数赋值,没有赋值的字段就不做更新.
这个问题花了两天时间才搞定.造成此速度的最大的原因是因为一开始引用了很低级的NHibernate版本(V1.0.2.0).此版本没有ExcuteUpdate方法,而我以为有其它方法可以实现此功

能.但是找了半天,才发现此版本只能用Session.CreateQuery(hql).List读出记录,然后再依次更新字段,最后再更新对象.这太愚蠢了.后面发现新版本的NHibernate(V2.1.1.4000)

有m_Session.CreateQuery(hql).ExecuteUpdate()功能,所以就引用了新的版本.但随之而来又发生了几个错误.
1.
pring.Core.CannotLoadObjectTypeException: Cannot resolve type [Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate] for object with name

'SessionFactory' defined in assembly [PersistenceLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], resource

[PersistenceLayer.Spring_nhibernate.xml] ---> System.TypeLoadException: Could not load type from string value

'Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate'.
在 Spring.Core.TypeResolution.TypeResolver.Resolve(String typeName)
在 Spring.Core.TypeResolution.GenericTypeResolver.Resolve(String typeName)
在 Spring.Core.TypeResolution.CachedTypeResolver.Resolve(String typeName)
在 Spring.Core.TypeResolution.TypeResolutionUtils.ResolveType(String typeName)
在 Spring.Objects.Factory.Support.AbstractObjectDefinition.ResolveObjectType()
在 Spring.Objects.Factory.Support.AbstractObjectFactory.ResolveObjectType(RootObjectDefinition rod, String objectName)
为这个问题找了很多资料,也问了几个人,包括NHibernate写得比较多日志的李永京同志,他说只搞NHibernate,没搞过NHibernate与SPRING.net结合,呵呵,太不好学了.
直到目前,这个问题还是没有解决.
不过从李身上发现,原来做这事不用spring.net也是OK的.啊,直到现在我还不是很明了spring.net到底有什么功能,强大到哪里?太失败了,于是自卑起来,发现自己的学习方法、学习

思路有问题。因为项目紧急,本来不适合用自己从未用过的技术,但为了公司以为的发展,决定咬牙搞定它,接着就在网上搜了一下Nhibernate,搜到个"NHibernate从入门到精通

",其实就是作者啊华的一个demo程序。而且是06年写的,太旧了。但能从中了解NHibernate与Spring.net,所以就没想太多的拿来用了。于是途中遇到一大堆问题,都是自己一步

一步解决的。直到这个问题(十四点),我是花了一天半都没解决,急死了。通过与李永京的对话发现,我用的版本的确太低,最重要的是可以不用spring.net来解决这个问题。
于是,我又打开从CodeProject下载的另一个项目(我从CodeProject下载了多个相关的项目),NHibernateSimpleDemo这个项目,就是单引用一个NHibernate.dll的,也是实现了

数据库与类的映射。数据库映射文件写在App.Config里面,直接用Configuration cfg = new Configuration();来完成Session的配置,于是我直接在原项目上改。首先把之前的类

与对应的映射文件换成自己的(UserCrossAuthen/ClientTactic),执行程序到 Configuration cfg = new Configuration();cfg.Configure();.有以下错误:

NHibernate.Cfg.HibernateConfigException: An exception occurred during configuration of persistence layer. ---> System.IO.FileNotFoundException: 未能找到文件

“E:\编程技术学习资料\持久层\CodeProject\NHibernateSimpleDemo\NHibernateSimpleDemo\bin\Debug\hibernate.cfg.xml”。
这个问题出现有几种原因:一:<hibernate-configuration xmlns="urn:nhibernate-configuration-2.0">要改成<hibernate-configuration xmlns="urn:nhibernate-

configuration-2.2">。二:XML文件的默认“复制到输出目录”为“不复制”,这里需要修改为“始终复制”。否则出现“failed: NHibernate.Cfg.HibernateConfigException :

An exception occurred during configuration of persistence layer. ----> System.IO.FileNotFoundException : 未能找到文件

“NHibernateSample\DAL.Test\bin\Debug\hibernate.cfg.xml””异常。

2.在执行到 m_SessionFactory = cfg.BuildSessionFactory();时会出现:
The ProxyFactoryFactory was not configured.\r\nInitialize 'proxyfactory.factory_class' property of the session-factory configuration section with one of the

available NHibernate.ByteCode providers.
注:这个错误是缺少引用NHibernate.ByteCode.LinFu.dll。而且在要在App.Config配置中的工厂类要写上 <property name="proxyfactory.factory_class">

NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>

3.
在执行到session.createSQLQuery(del).executeUpdate();时出现如下错误:
ex = {"could not execute native bulk manipulation query:update ClientTactic ct set ct.CompanyName='jimmy' where ct.TacticId=3[SQL: update ClientTactic ct set

ct.CompanyName='jimmy' where ct.TacticId=3]"}
改成:m_Session.CreateQuery(hql).ExecuteUpdate();

十五:
解决一次插入多条数据的问题:还是用for循环,分别Session.SaveOrUpdate(item);用到事务处理.

十六:
解决连表查询问题,这个暂时用到hql语句应付着.

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lateknow/archive/2009/12/02/4924856.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: