Hi everybody!
I`m using
Hibernate version:1.0.2, and
MSSQL 2000 - MSDE
in my table "Ref1" I create column with type -
Money.
In my mapping and in code i use type
Decimal
to hold data from the column.
Mapping:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly ="NHDomainLib" >
<class name="NHDomainLib.Ref1, NHDomainLib" table="Ref1">
<id name="Id" column="Id" type="Int32" unsaved-value="0" >
<generator class="native"/>
</id>
<property name="MValue" column="mvalue" type="Decimal"/>
</class>
</hibernate-mapping>
Class Ref1
[code]
public class Ref1
{
private int _Id;
private decimal _MValue;
public Ref1(){}
public int Id
{
get {return _Id;}
set {_Id =value;}
}
public decimal MValue
{
get {return _MValue;}
set {_MValue = value;}
}
}
[code]
When i want to save instance of Ref1
with property MValue = 1000 000 000 000 00m;
[code]
Ref1 r1= new Ref1();
r1.MValue = 1000 000 000 000 00m;
ITransaction tx = session.BeginTransaction();
try{
session.SaveOrUpdate(r1);
tx.Commit();
}
cacth
{
tx.Rollback()
throw;
}
[/code]
I receive exception
could not insert: [NHDomainLib.Ref1]
at NHibernate.Persister.EntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session)
at NHibernate.Persister.EntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
at NHibernate.Impl.ScheduledIdentityInsertion.Execute()
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable)
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, Key key, IClassPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IClassPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
at NHDomainLib._Main.Main() in c:\documents\nhdomainlib\_main.cs:line 44
this exception disappear when i save any number less then -10E14 .
in generated sql code
exec sp_executesql N'INSERT INTO Ref1 (mvalue) VALUES (@p0); select SCOPE_IDENTITY()',
N'@p0 decimal(19,5)',
@p0 = -10000000000000.00000
i see that property with type Decimal converted to the parameted
with type
decimal(19,5)
BUT THIS IS WRONG transformation!!! In MSSql type Money must be mapped to the type Decimal(19,4) but NOT A Decimal(19,5)!!!
I solved this by changing a small code in file NHibernate\Driver\SqlClientDriver.cs
in method
protected override IDbDataParameter GenerateParameter( IDbCommand command, string name, Parameter parameter, Dialect.Dialect dialect )
code
case DbType.Decimal:
pps = parameter as ParameterPrecisionScale;
dbParam.Precision = 19;
dbParam.Scale = 5;
break;
changed on
case DbType.Decimal:
pps = parameter as ParameterPrecisionScale;
dbParam.Precision = 19;
dbParam.Scale = 4;[color=red]
break;
and after that rebuilding NHIbernate.dll I successfuly save my
entity with value 100000000000000m.
May be exist other way to do this without changing the internals of HNIbernate and rebuilding it ??
PS: I founded very interesting and funny comment in file SqlClientDriver.cs line - 167
case DbType.Decimal:
pps = parameter as ParameterPrecisionScale;
[color=red]TODO: remove this hardcoding...
dbParam.Precision = 19;
dbParam.Scale = 5;