Why NHibernate updates DB on commit of read-only transaction
http://www.zvolkov.com/clog/2009/07/09/why-nhibernate-updates-db-on-commit-of-read-only-transaction/
Always be careful with NULLable fields whenever you deal with NHibernate. If your field is NULLable in DB, make sure corresponding .NET class uses Nullable type too. Otherwise, all kinds of weird things will happen. The symptom is usually will be that NHibernate will try to update the record in DB, even though you have not changed any fields since you read the entity from the database.
The following sequence explains why this happens:
- NHibernate retrieves raw entity's data from DB using ADO.NET
- NHibernate constructs the entity and sets its properties
- If DB field contained NULL the property will be set to the defaul value for its type:
- properties of reference types will be set to null
- properties of integer and floating point types will be set to 0
- properties of boolean type will be set to false
- properties of DateTime type will be set to DateTime.MinValue
- etc.
- Now, when transaction is committed, NHibernate compares the value of
the property to the original field value it read form DB, and since the
field contained NULL but the property contains a non-null value,
NHibernate considers the property dirty, and forces an update of the
enity.
Not only this hurts performance (you get
extra round-trip to DB and extra update every time you retrieve the
entity) but it also may cause hard to troubleshoot errors with DateTime
columns. Indeed, when DateTime property is initialized to its default
value it's set to 1/1/0001. When this value is saved to DB, ADO.NET's
SqlClient can't convert it to a valid SqlDateTime value since the
smallest possible SqlDateTime is 1/1/1753!!! The exception it throws
looks like this:
NHibernate.Event.Default.AbstractFlushingEventListener - Could not synchronize database state with session NHibernate.HibernateException: at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value) at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value) at System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime, Byte cb) at at at at at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery() at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery() --- End of inner exception stack trace --- at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery() at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps) at NHibernate.AdoNet.AbstractBatcher.ExecuteBatch() at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) at NHibernate.Engine.ActionQueue.ExecuteActions() at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) at NHibernate.Impl.SessionImpl.Flush() at NHibernate.Transaction.AdoTransaction.Commit() |
The easiest fix is to make the class
property use Nullable<T> type, in this case "DateTime?".
Alternatively, you could implement a custom type mapper by implementing
IUserType with its Equals method properly comparing DbNull.Value with
whatever default value of your value type. In our case Equals would need
to return true when comparing 1/1/0001 with DbNull.Value. Implementing a
full-functional IUserType is not really that hard but it does require
knowledge of NHibernate trivia so prepare to do some substantial
googling if you choose to go that way.
Hope this helps somebody!
Why NHibernate updates DB on commit of read-only transaction的更多相关文章
- ABAP-关于隐式与显式的DB Commit
转载:https://www.cnblogs.com/liaojunbo/archive/2011/07/11/2103491.html 1.显式的DB Commit 显式的DB Commit并没有对 ...
- The Architecture of Open Source Applications: Berkeley DB
最近研究内存关系数据库的设计与实现,下面一篇为berkeley db原始两位作为的Berkeley DB设计回忆录: Conway's Law states that a design reflect ...
- spring.net 集成nhibernate配置文件(这里暴露了GetCurrentSession 对于 CurrentSession unbond thread这里给出了解决方法)
我这里主要分成了两个xml来进行spring.net管理实际情况中可自己根据需要进行分类 Dao2.xml <?xml version="1.0" encoding=&quo ...
- NHibernate系列文章十四:NHibernate事务
摘要 NHibernate实现事务机制非常简单,调用ISession.BeginTransaction()开启一个事务对象ITransaction,使用ITransaction.Commit()提交事 ...
- NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...
- NHibernate Session-per-request and MiniProfiler.NHibernate
NHibernate Session-per-request and MiniProfiler.NHibernate 前言 1.本文以mvc3为例,借鉴开源项目 NerdDnner项目完成nhiber ...
- Python DB operation
mysql http://www.cnblogs.com/zhangzhu/archive/2013/07/04/3172486.html 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目 ...
- sqlachemy 获取新创建对象的id,flush与commit
for account_info in valid_account_detail: try: account = account_info.get('account') password = acco ...
- 关于NHibernate的一些代码
SessionManager using System; using System.IO; using System.Runtime.Serialization; using System.Runti ...
随机推荐
- 【Spring】Spring系列4之Spring支持JDBC
4.Spring支持JDBC 4.1.使用JdbcTemplate简化JDBC开发 也可以这么用(不推荐): 4.2.使用NamedParameterJdbcTemplate
- 《ASP.NET1200例》各种类型文件汇总
aspx是页面文件 ascx是用户控件,用户控件必须嵌入到aspx中才能使用. ascx是用户控件,相当于模板 其实ascx你可以理解为Html里的一部分代码, 只是嵌到aspx里而已, 因为aspx ...
- Bulb Switcher
There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every ...
- sc 与net命令的区别
windows服务操作命令有sc和net 两个命令; sc stop serviceName sc start serviceName net stop serviceName net start ...
- Power Strings(poj 2406)
题意:求字符串中循环节出现的次数 KMP!!! #include<cstdio> #include<iostream> #include<cstring> #def ...
- Android之shape属性详解
有时候 ,为了满足一些需求,我们要用到 shape 去定义 一些背景,shape 的用法 跟图片一样 ,可以给View设置 Android:background="@drawable/sha ...
- windows网络版象棋的实现
要构建网络版象棋,首先应该创建服务器与客户端,建立socket连接 1) 开局,你是什么颜色 2)选择棋子, 3)走棋 4)悔棋(悔棋悔两步) 5)认输 网络实现: 1)建立连接 a.主机,建立监听s ...
- Hadoop 1.1.2 eclipse plugin 编译 win7 集成
Windows平台上使用ANT编译Hadoop Eclipse Plugin 一.准备工作: 1.安装JDK 下载页面:http://www.oracle.com/technetwork/java ...
- [转]有关USES_CONVERSION
转自:http://blog.csdn.net/p40614021/article/details/6778100 ATL:转换宏是各种字符编码之间进行转换的一种很方便的方式,在函数调用时,它们显得非 ...
- SecureCRT乱码
http://jingyan.baidu.com/article/948f59245be128d80ff5f9aa.html