Hi all,
my application reads from a table that has floating point numbers (Oracle type = FLOAT, C# type = double). One row has a number that has 24 digits after the decimal point. When NHibernate tries to load this row, I get an Oracle error:
OCI-22053: overflow error
After doing some research on the web, I found that this is a common problem. The common recommendation is to round the number in the SQL. I changed my NHibernate mapping document
from
<property name = "Foo" column = "foo"/>
to
<property name = "Foo" formula = "round(foo,10)"/>
And this got my program running. But this is not a good solution at all:
1. it doesn't support writing to that column,
2. every single mapping file needs to be modified,
3. small performance impact (probably negligible).
Is there a cleaner solution available? Ideally one where I could set an option on the NHibernate configuration, that I want underflows to be ignored.
NHibernate.Cfg.Configuration:
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="hibernate.dialect" value="NHibernate.Dialect.Oracle9Dialect"/>
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.OracleClientDriver"/>
<entry key="hibernate.max_fetch_depth" value="-1"/>
NHibernate version:
1.2.0.4000
Full stack trace of any exception that occurs:
2008-10-07 11:26:29,761 [9] ERROR NHibernate.Util.ADOExceptionReporter - OCI-22053: overflow error
2008-10-07 11:26:29,761 [9] ERROR NHibernate.Collection.AbstractPersistentCollection - Failed to lazily initialize a collection
NHibernate.ADOException: could not initialize a collection: [HistoricalInstrumentInfo.HistoricalDebtInfo.Records#301][SQL: SELECT records0_.HISTODEBT_ID as HISTODEBT1___1_, records0_.HISTODEBT_ID as HISTODEBT1_1_, records0_.HISTODEBT_DTVALO as HISTODEBT2_1_, records0_.HISTODEBT_DTVALO as HISTODEBT2___1_, records0_.HISTODEBT_ID as HISTODEBT1_1_0_, records0_.HISTODEBT_DTVALO as HISTODEBT2_1_0_, records0_.HISTODEBT_PRICE as HISTODEBT3_1_0_, records0_.HISTODEBT_YIELD as HISTODEBT4_1_0_, records0_.HISTODEBT_ASM as HISTODEBT5_1_0_, records0_.HISTODEBT_ASMBID as HISTODEBT6_1_0_, records0_.HISTODEBT_ASMASK as HISTODEBT7_1_0_, records0_.HISTODEBT_ZCSPREAD as HISTODEBT8_1_0_, records0_.HISTODEBT_SWSPREAD as HISTODEBT9_1_0_, records0_.HISTODEBT_SWINTERP as HISTODEBT10_1_0_, records0_.HISTODEBT_TED as HISTODEBT11_1_0_, records0_.HISTODEBT_EONIA as HISTODEBT12_1_0_, records0_.HISTODEBT_BUNDSPREAD as HISTODEBT13_1_0_, records0_.HISTODEBT_BOBLSPREAD as HISTODEBT14_1_0_, records0_.HISTODEBT_SCHZSPREAD as HISTODEBT15_1_0_, records0_.HISTODEBT_REPORATE as HISTODEBT16_1_0_, records0_.HISTODEBT_REPOSPREAD as HISTODEBT17_1_0_, records0_.HISTODEBT_PVBP as HISTODEBT18_1_0_, records0_.HISTODEBT_CONVEXITY as HISTODEBT19_1_0_, records0_.HISTODEBT_DTSETTLEMENT as HISTODEBT20_1_0_ FROM TDEBT_HISTOVAL records0_ WHERE records0_.HISTODEBT_ID=?] ---> System.Data.OracleClient.OracleException: OCI-22053: overflow error
at System.Data.OracleClient.OracleException.Check(OciErrorHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleNumber.ToUInt32(OciErrorHandle errorHandle, Byte[] value)
at System.Data.OracleClient.OracleNumber.ToDecimal(OciErrorHandle errorHandle, Byte[] value)
at System.Data.OracleClient.OracleNumber.MarshalToDecimal(NativeBuffer buffer, Int32 valueOffset, OracleConnection connection)
at System.Data.OracleClient.OracleColumn.GetDecimal(NativeBuffer_RowBuffer buffer)
at System.Data.OracleClient.OracleColumn.GetValue(NativeBuffer_RowBuffer buffer)
at System.Data.OracleClient.OracleDataReader.GetValue(Int32 i)
at System.Data.OracleClient.OracleDataReader.get_Item(Int32 i)
at NHibernate.Type.DoubleType.Get(IDataReader rs, Int32 index)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner)
at NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner)
at NHibernate.Loader.Loader.Hydrate(IDataReader rs, Object id, Object obj, ILoadable persister, ISessionImplementor session, String[][] suffixedPropertyColumns)
at NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, Type instanceClass, EntityKey key, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session)
at NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, EntityKey key, LockMode lockMode, EntityKey optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)
--- End of inner exception stack trace ---
at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)
at NHibernate.Loader.Collection.CollectionLoader.Initialize(Object id, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session)
at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing)
at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing)
Name and version of the database you are using:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
|