3

Fluent NHibernate 1.2.0.712を使用してclobフィールドをOracle 10gに対してマップしようとしました。私はSystem.Dataプロバイダーを使用しています。既定で利用可能で、以前のクライアントの問題のためにODP.Netへの参照を追加しないようにしようとしていました。Fluent NHibernate、Oracle 10gおよびOracleClientConfiguration.Oracle10を使用したクロップのマッピング

私がマッピングされたCLOB特性を持つエンティティを挿入しようとすると、しかし、私はエラーを取得:

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」の値を使用して以下を試しました。いずれも機能しませんでした:

ODPをプロバイダーとして追加する以外にも、この修正に関する提案はありますか?

+0

私は、Microsoftのプロバイダをしませんが、ODP.NETを使用すると、CLOBの場合は特別なことをする必要はありません、彼ら通常の文字列としてマップされます(ただし、空の文字列を空のclobの代わりにnullとして挿入しようとします)。 'plaparte.disposiciones'プロパティは文字列ですか? – cremor

答えて

0

this postは、このエラーの原因とその解決方法を完全に記述しています。ブログ記事で提供

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.

ソリューション:カスタムNHibernateはOracleドライバ:

/// <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; 
    } 
} 
+0

これは理論的に質問に答えるかもしれませんが、こちらの回答の重要な部分を含め、参考にするためのリンクを提供することが望ましいでしょう(http://meta.stackexchange.com/q/8259)。 – Aaronaught

+0

ちょっと言ってくれてありがとう。 – Lodewijk

関連する問題