用nhibernate的几点小经验

简介: 最近几个月都在用nhibernate做项目。写几点经验。 1. 解决Transient object exception 原项目是用Entity Framework做的。现在是用nhibernate代替Entity framework. 原来的Entity framework可以new 一系列的对象,这些对象之间还有一对多关系,这些对象都没有保存,然后一起保存,就会出现这个问题。

最近几个月都在用nhibernate做项目。写几点经验。

1. 解决Transient object exception

原项目是用Entity Framework做的。现在是用nhibernate代替Entity framework. 原来的Entity framework可以new 一系列的对象,这些对象之间还有一对多关系,这些对象都没有保存,然后一起保存,就会出现这个问题。例如:Project 对应多个ProjectVersion, 一个ProjectVersion对应多个 ProjectVersionAttribute, 在最后的时候保存Project, 此时Project, ProjectVersion, ProjectVersionAttribute都是没有保存的。都是刚new出来的。 调用Project.Save(); 即出现这个问题。后来查阅文档, 原来是map的问题,没有设置级联保存。于是就在map文件里加上了cascade.all。这样的话,在处理刚才这种情况时就没有问题。所有这些没有保存的对象都会由于这个级联设置而保存了。Entity framework的map是在dbml中设置一下就可以了。而nhibernate需要写map文件。这个差别还是比较大的。

2. 解决对象树中的子对象不刷新问题。

还以Project -> ProjectVersion -> ProjectVersionAttribute来说示例。在ProjectVersionAttribute中加了一个新对象,新对象保存了。然后在Project级别重新Load数据,然后通过Project的属性来一层层地访问所有的子对象。但是这个对象树总是没有新加入的对象。这对我们遍历这个对象树有点问题。这个问题开始以为是跟cascade有关。试着加上了cascade,但是没有作用,新加的子对象还是没有出现在对象树中。最后没有办法了,只有放弃当前Session,新建一个Session,再装入对象树,结果就对了。

 

3. nhibernate用LINQ和lamda表达式

默认情况下nhibernate用HQL, 在.net版本下,可以用LINQ来写查询。nhibernate可以利用LINQ的语句。Entity framework写的应用,原来有很多LINQ语句,有的还特别复杂,长达好几页。可以用NHibernate.Linq名称空间,然后用形式如:session.Query<User>().Where(u => u.Username== username)或者session.QueryOver<User>().Where(u => u.Username== username),就可以跟LINQ和lamda表达式很兼容了。Query和QueryOver两个大体都差不多。我们项目里实际用的是QueryOver。通过这种方式,原来的Entity framework的有LINQ和lamda query就可以不用改了。绝大部分都可以用。

 

4. NullPointerException的解决方式

在nhibernate中一条条记录都成了一个个对象。数据库表的外连接在nhibernate的map中是reference。这个外键是不允许空的。数据库中外键字段不可能空的。但是内存中的对象就不一样了。内存中的对象某个属性可以随便取什么值,为空也可以。我们在LINQ查询lamda表达式中引用到了某个属性,如果这个属性为null,则会抛出NullPointerException。这种情况在nhibernate中发生很普遍,而Entity framework这种问题就少些。对于这个NullPointerException,我们需要保证每个属性都有正确的值,而不能是只给主键赋一个值就行了。nhibernate不会自动根据主键去取到除主键外的其他字段的。我们得构造一个完整的对象。这样在查询的时候就不会出现NullPointerException的问题。有时一个表里有很多条记录,如果某个字段允许空,同时某些记录的该字段是空值,查询条件里的lamda表达式有用到该字段。很有可能出现NullPointerException的问题。按以上条件查找哪些lamda表达式涉及的字段,然后给LINQ查询加上检查空的条件。这样就可以避免出NullPointerException了。

 

5. 同一记录被两个Session装载了。

因为asp.net的环境是多线程的。可能会出现两个以上的Session, 如果同条数据库记录被两个Session装载到内存中,其中一个Session就会报错。这个问题就是属于Session管理的问题了。数据库表有一定的工作区域的,比如有的表是跟用户的,有的是跟项目的,如果在业务上可以让不同Session总是访问不同的数据。那么这个问题就不会出现了。但是数据库里总是有一些公用的数据。这些数据呢我们可以一次性读入到内存里缓存起来。缓存以后我们就让这些公用数据同原来的Session脱离。让其处于瞬态。需要的时候再与某个Session连接,进入持久化状态。

 

6. nhibernate数据库事务的粒度问题

最开始的时候我们 nhibernate的数据库事务粒度相当小,所有insert, update, delete, select都单独成一个事务。后来发现这样不能适合实际的要求。有些时候需要引入更大的数据库事务粒度。比如好几个insert, update, delete构成一个事务。这个事务的控制就在商务逻辑的类中来管理的。这里可以引入Unit of work模式,也可以引入自己管理的事务模式。

 

目录
相关文章
|
12月前
|
运维 程序员
程序员成长第九篇:真实项目中的注意事项
程序员成长第九篇:真实项目中的注意事项
39 0
|
XML Java 数据库连接
Spring框架:第一章:介绍和准备工作
Spring框架:第一章:介绍和准备工作
Spring框架:第一章:介绍和准备工作
|
SQL 自然语言处理 关系型数据库
数据库知识点太多?作为测试掌握这些就够了【精简重点版 >直击面试>建议收藏】
数据库知识点太多?作为测试掌握这些就够了【精简重点版 >直击面试>建议收藏】
96 0
数据库知识点太多?作为测试掌握这些就够了【精简重点版 >直击面试>建议收藏】
|
数据库
高质量代码优化!谈谈重构项目中if-else代码的几点建议
本篇文章探讨了代码的重构以及优化,主要针对代码中大量的条件判断if-else语句问题提出了具体的优化建议。介绍了优化if-else语句的几种有效的方法,包括switch,接口interface以及数据库实现对条件语句进行的优化。
144 0
高质量代码优化!谈谈重构项目中if-else代码的几点建议
|
新零售 移动开发 人工智能
程序员写好技术文章的几点小技巧
去年成为了内网技术分享平台的年度作者,受邀写一篇关于“如何写好文章”的文章。我本身并不喜欢写字,去年写的几篇文章,涉及的话题自带流量,所以阅读量多了一些,谈不上有多擅长。不过还是决定分享一下自己在写文章时用到的一些小技巧,希望对大家有帮助。
程序员写好技术文章的几点小技巧
|
运维 前端开发 Cloud Native
想成为全栈工程师,要做到哪几点?
如何成为一名全栈工程师?需要具备哪些技术积累?成为全栈工程师有哪些好处?希望本文能为期望成为全栈工程师的同学提供一点帮助,和同学们一起分享交流。
想成为全栈工程师,要做到哪几点?
|
项目管理
带你读《软件项目管理案例教程(第4版)》之二:项目确立
本书以案例形式讲述软件项目管理过程,借助路线图讲述项目管理的理论、方法及技巧,覆盖项目管理十大知识域的相关内容,重点介绍软件这个特殊领域的项目管理。本书综合了多个学科领域,包括范围计划、成本计划、进度计划、质量计划、配置管理计划、风险计划、团队计划、干系人计划、沟通计划、合同计划等的制定,以及项目实施过程中如何对项目计划进行跟踪控制。该书取材新颖,注重理论与实际的结合,通过案例分析帮助读者消化和理解所学内容,既适合作为高等院校计算机、软件及相关专业高年级本科生和研究生的教材,也适合作为广大软件技术人员和项目经理培训的教材,还可作为软件开发项目管理人员的参考书。
|
Java
关于软件工程的几点思考
来阿里已经很长一段时间了,从刚开始来我就想写点关于软件工程,服务化和开发效率的个人理解,却一直没有想好怎么写,一直在心里筹划思考该如何准确地表达我所想的内容,也能够给别人带来一些有价值的信息,但是拖了很久了,想想还是写出来罢,没有必要追求那么完美,欢迎拍砖。(顺便说下,有观点认为拖延症患者都有或多或少的完美主义倾向,处女座的同学验证下哈。) ## 1 什么是软件工程? 服务化其实是一个软
2351 0
|
编解码 Android开发
从手工打造到工厂设计模式的演变历程
自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程0...
1750 0