如果使用到Oracle的CLOB字段,那么NHibernate会遇到很诡异的“ORA-01461:仅可以插入LONG列的LONG值赋值”错误。关于此错误的分析和解决方法在这里(http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx)有详细的介绍,实现NHibernate的自定义类型IUserType接口 :
public abstract class PatchForOracleLobField : IUserType
{
public PatchForOracleLobField()
{
}
public bool IsMutable
{
get { return true; }
}
public System.Type ReturnedType
{
get { return typeof(String); }
}
public SqlType[] SqlTypes
{
get
{
return new SqlType[] { NHibernateUtil.String.SqlType };
}
}
public object DeepCopy(object value)
{
return value;
}
public new bool Equals(object x, object y)
{
return x == y;
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
return NHibernate.NHibernateUtil.StringClob.NullSafeGet(rs, names[0]);
}
public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
public object Replace(object original, object target, object owner)
{
return original;
}
}
public class OracleClobField : PatchForOracleLobField
{
public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (cmd is OracleCommand)
{
//CLob、NClob类型的字段,存入中文时参数的OracleDbType必须设置为OracleDbType.Clob
//否则会变成乱码(Oracle 10g client环境)
OracleParameter param = cmd.Parameters[index] as OracleParameter;
if (param != null)
{
param.OracleType = OracleType.Clob;// 关键就这里啦
param.IsNullable = true;
}
}
NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index);
}
}
用此方法解决了CLOB字段2000-4000字的问题,可是今天又遇到了个新的“ORA-01084: OCI 调用中的参数无效”错误,google了一下,大概是说CLOB字段如果为null或’’时就会出这个错。
解决的办法:
将OracleClobField.NullSafeSet中的
if (cmd is OracleCommand) ….
改为
if ((cmd is OracleCommand) && !string.IsNullOrEmpty(value as string))
如果值是空或者空字符串的话就让NHibernate当默认的varchar2处理。
from:http://wuchang.cnblogs.com