1

私は NHibernate 3.3 と ODP.NET を使用して Oracle11g データベースに永続化しています。これは、以下に関連する構成のセクションです。

<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>

byte[] プロパティを BLOB フィールドにマッピングし、次のように挿入ストアド プロシージャを実行するブロックを設定しています。

  <class name="Digital" table="DIGITALS">
    <id name="Id" column="COD_DIGITAL">
      <generator class="increment" />
    </id>
    <property name="File" column="FILE" />

    <sql-insert>begin PKG_DIGITALS.insert_sp(?,?); end;</sql-insert>

デジタルエンティティは、サイズが 32k 以下のファイルで正常に保持されます。しかし、サイズが 32k を超えるファイルで [ORA-01460: 実装されていない、または不当な変換が要求されました] というエラーが発生します。

ドライバーの制限ですか?どうすればこれを回避できますか?

4

1 に答える 1

0

同じ問題が発生しました(NHibernate 3.3.1.4000、Oracle 11g)。NHibernatesOracleDataClientDriverはdbParam.DbType=DbType.Binaryを設定します。これにより、この32Kの制限が発生します。dbParam.OracleDbType = OracleDbType.Blobを設定すると、制限はなくなります。これをアーカイブするために、独自のOracleドライバーを作成しました。

public class OracleOdpClientDriver : OracleDataClientDriver
{
  protected override void InitializeParameter(System.Data.IDbDataParameter dbParam, string name, NHibernate.SqlTypes.SqlType sqlType)
  {
    base.InitializeParameter(dbParam, name, sqlType);
    var oraParam = dbParam as OracleParameter;
    if (oraParam != null)
    {
      if (sqlType.DbType == System.Data.DbType.Binary)
        // Use Oracle Blob instead of Binary to prevent a 32K limit.
        oraParam.OracleDbType = OracleDbType.Blob;
      else if (sqlType.DbType == System.Data.DbType.String && sqlType.LengthDefined && sqlType.Length >= 32768)
        // StringClob params must not be mapped to Varchar2 because that has a 32K limit.
        oraParam.OracleDbType = OracleDbType.Clob;
    }
  }

最後に、ドライバーを構成に登録する必要があります。

<property name="connection.driver_class">MyDataAccess.OracleOdpClientDriver, MyDataAccess</property>

ここここも参照してください。これはNHibernateに統合するのに十分なソリューションであるかどうか疑問に思います。

于 2013-03-12T14:23:22.130 に答える