使用Fluent NHibernate,Oracle 10g和OracleClientConfiguration.Oracle10来映射clobs [英] Mapping clobs using Fluent NHibernate, Oracle 10g and OracleClientConfiguration.Oracle10

查看:250
本文介绍了使用Fluent NHibernate,Oracle 10g和OracleClientConfiguration.Oracle10来映射clobs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图用Fluent NHibernate 1.2.0.712来映射一个clob字段对Oracle 10g。我使用的System.Data提供程序,因为它是默认可用,并试图避免添加引用ODP.Net由于以前的客户端问题。但是,当我尝试插入具有映射clob属性的实体时,出现以下错误:
$ b

ORA- 01461:只能将LONG值绑定到LONG列中插入



我试图通过使用以下约定来解决此问题,并使用[StringLength (4000)]:

  public class StringLengthConvention:AttributePropertyConvention< StringLengthAttribute> 
{
protected override void Apply(StringLengthAttribute attribute,IPropertyInstance instance)
{
instance.Length(attribute.MaximumLength);
}
}

这是行不通的。

然后我试着用下面的TEXT,CLOB和clob值。

  public class plaparteMappingOverride:IAutoMappingOverride< plaparte> 
{
public void Override(AutoMapping< plaparte> mapping)
{
Map(x => x.disposiciones).CustomSqlTypeIs(TEXT);






$ b

有没有人有进一步的建议, ODP作为提供者?

解决方案

以供参考:这篇文章完全描述了导致这个错误的原因以及如何解决这个错误。


ORA-01461:只能绑定LONG值才能插入LONG列



这个错误不是很有帮助,而且会使用goggling可能会导致有关Oracle补丁等主题
。实际上,这是微软的oracle客户端驱动程序的
错误。驱动程序错误
推断被保存的字符串的列类型,并尝试强制
服务器将LONG值更新为CLOB / NCLOB列类型。不正确行为的
原因更加隐晦,只有满足以下所有条件才会发生



  1. 当我们设置IDbDataParameter.DbType = DbType.String
  2. $ b $时,设置IDbDataParameter.Value =(字符串的长度为:4000> length> 2000)
  3. b
  4. 当DB列是类型NCLOB / CLOB时

不幸的是NHibernate 2.0的默认行为是做
以上,当
使用nhibernate和oracle的时候,很可能会遇到这个丑陋的bug。

提供的解决方案在博客文章中:自定义的NHibernate Oracle驱动程序:

  ///< summary> 
///初始化参数。
///< / summary>
///< param name =dbParam> db参数。
///< param name =name>名称。
///< param name =sqlType> SQL的类型。
protected override InitializeParameter(System.Data.IDbDataParameter dbParam,string name,global :: NHibernate.SqlTypes.SqlType sqlType)
{
base.InitializeParameter(dbParam,name,sqlType);

//System.Data.OracleClient.dll驱动程序产生一个异常
//我们设置IDbDataParameter.Value =(字符串,其长度为4000>长度> 2000)
//当我们设置IDbDataParameter.DbType = DbType.String
//当DB列的类型为NCLOB / CLOB
//以上是NHibernate的默认行为.OracleClientDriver
/ /所以我们使用内置的StringClobSqlType来告诉驱动程序使用NClob Oracle类型
//这对于两个NCLOB / CLOB都是没有问题的。
//映射文件需要更新才能使用StringClob作为属性类型
if((sqlType is StringClobSqlType))
{
((OracleParameter)dbParam).OracleType = OracleType.NClob;
}
}


I've been trying to map a clob field using Fluent NHibernate 1.2.0.712 against Oracle 10g. I'm using System.Data provider as it's available by default and was trying to avoid adding reference to ODP.Net due to previous client issues.

However, when I try to insert entities with mapped clob properties, I get the error:

ORA-01461: can bind a LONG value only for insert into a LONG column

I've tried to fix this by using the below convention, and decorating the appropriate property with [StringLength(4000)]:

public class StringLengthConvention : AttributePropertyConvention<StringLengthAttribute>
{
    protected override void Apply(StringLengthAttribute attribute, IPropertyInstance instance)
    {
        instance.Length(attribute.MaximumLength);
    }
}

This didn't work.

Then I tried the below using "TEXT", "CLOB" and "clob" values. Neither worked:

    public class plaparteMappingOverride : IAutoMappingOverride<plaparte>
    {
        public void Override(AutoMapping<plaparte> mapping)
        {
           Map(x => x.disposiciones).CustomSqlTypeIs("TEXT");
        } 
    }

Does anyone have further suggestions for this fix other than adding ODP as the provider?

解决方案

For future reference: this post perfectly describes what causes this error and how you can solve it.

ORA-01461: can bind a LONG value only for insert into a LONG column

This error is not very helpful and goggling it will most likely result in topics regarding oracle patches and the like. In reality this is a bug with the microsoft oracle client driver. The driver mistakenly infers the column type of the string being saved, and tries forcing the server to update a LONG value into a CLOB/NCLOB column type. The reason for the incorrect behavior is even more obscure and only happens when all the following conditions are met.

  1. when we set the IDbDataParameter.Value = (string whose length is : 4000 > length > 2000 )
  2. when we set the IDbDataParameter.DbType = DbType.String
  3. when DB Column is of type NCLOB/CLOB

Unfortunately NHibernate 2.0's default behavior is to do exactly the above, making it quite more likely to run into this ugly bug when using nhibernate and oracle.

Solution offered in the blog post: a custom NHibernate Oracle Driver:

/// <summary>
/// Initializes the parameter.
/// </summary>
/// <param name="dbParam">The db param.
/// <param name="name">The name.
/// <param name="sqlType">Type of the SQL.
protected override void InitializeParameter(System.Data.IDbDataParameter dbParam, string name, global::NHibernate.SqlTypes.SqlType sqlType)
{
    base.InitializeParameter(dbParam, name, sqlType);

    //System.Data.OracleClient.dll driver generates an exception
    //we set the IDbDataParameter.Value = (string whose length: 4000 > length > 2000 )
    //when we set the IDbDataParameter.DbType = DbType.String
    //when DB Column is of type NCLOB/CLOB
    //The Above is the default behavior for NHibernate.OracleClientDriver
    //So we use the built-in StringClobSqlType to tell the driver to use the NClob Oracle type
    //This will work for both NCLOB/CLOBs without issues.
    //Mapping file will need to be update to use StringClob as the property type
    if ((sqlType is StringClobSqlType))
    {
        ((OracleParameter)dbParam).OracleType = OracleType.NClob;
    }
}

这篇关于使用Fluent NHibernate,Oracle 10g和OracleClientConfiguration.Oracle10来映射clobs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆