在使用NHiberanter,创建一个session上下文,进行语句执行时,出现了标题所示错误。控制台调用代码如下:
public static void Main(string[] args) { //NHibernateProfiler程序分析初始化 //HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); ISessionFactory factory = new Configuration().Configure().BuildSessionFactory(); ISession session = factory.OpenSession(); using (ITransaction rs = session.BeginTransaction()) { var pm = session.Get<LeaseUser>(154143);//出现错误 var _model = session.QueryOver<LeaseUser>().Where(x => x.UserName=="陶*林").List(); var sModel = session.CreateSQLQuery("select * from LEASE_USER where user_name=:num").AddEntity(typeof(LeaseUser)) .SetParameter("num", "包磊");
通过session的get方法,获取一个指定实体,提示持久化对象没有在配置文件中加载到。配置文件如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 This template was written to work with NHibernate.Test. 4 Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 5 for your own use before compile tests in VisualStudio. 6 --> 7 <!-- This is the System.Data.OracleClient.dll provider for Oracle from MS --> 8 <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 9 <session-factory name="NHibernate.Test"> 10 <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property> 11 <property name="connection.connection_string"> 12 User ID=admin;Password=admin001;Data Source=127.0.0.1/orcl 13 </property> 14 <property name="show_sql">true</property> 15 <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property> 16 <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property> 18 </session-factory> 19 </hibernate-configuration>
诱因一:该配置时直接从下载的Nh包中的oracle.cfg.xml移植过来的,通过查询资料,发现少了一行:<mapping assembly="Domain"/>,该mapping需要添加在session-factory的最后位置,其目的是加载持久化对象的映射文件的所在程序集:
1 <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property> 2 <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property> 3 <mapping assembly="Domain"/><!--用于加载实体映射文件所在的程序集--> 4 </session-factory>
诱因二:与Fluent Nhibernate混肴了。使用如下代码片段加载hibernate配置文件,它会去查找配置文件mapping配置的程序集下的所有xml映射文件,因为使用了Fluent Nhibernate的map映射,所以是查找不出对应的xml,也即持久化对象的映射未在配置中查找到:
1 ISessionFactory factory = new Configuration().Configure().BuildSessionFactory();
备忘:
一。向项目中添加指定的数据库xx.cfg.xml文件的时候,需要统一修改名称为:hibernate.cfg.xml
二。hibernate.cfg.xml文件属性->复制到输入目录->始终复制或如果较新则复制
三。直接引入的数据库对应的cfg.xml文件,是没有mapping节点的。但这个是必不可少的属性节点。
四。如果没有实现三,还可以让NHibernate自动到程序集加载所有嵌入式资源xml映射文件,如下代码:
1 Configuration cfg = new Configuration() 2 .AddAssembly( "Domain" );
五。如果没有实现一,也可以使用如下代码,添加一个不同的XML配置文件
1 ISessionFactory sf = new Configuration() 2 .Configure("/path/to/config.cfg.xml") 3 .BuildSessionFactory();
六。NHibernate中的一级缓存,是个字典值。字典的key就是主键值。如果key值相同,则认为是同一个对象。如果映射结构里没有配置主键值,NHibernate就无法管理session的缓存,就会报异常。