Decimal problem

Hi VP,

I think this will be one of my last bug reports, because you are fixing all of them very quickly!! :slight_smile: and my evaluation it is almost finished (your software and specially your support have a high punctuation, don’t worry).

But, today I had a problem with a “decimal” field.

I think I have done it right (never used them before). Follow this short steps:

  • Create new package “pack1”
  • Create new class “class1”
  • Add an attribute “att1: decimal”

Then, as always, sync to erd and generate code (use XML mapping).

Then, examine the class1.hbm.xml file:

<property name=“Att1” column=“Att1” type=“decimal, Base” not-null=“false”/>

(“Base” is my project’s assembly)

So, DBVA did not recognize the “decimal” type as NHibernate internal “Decimal” ( NHibernate Basic Types 5.2.2 ) and instead it thinks it is a user-defined type.

Further on, look at the C# generated code:
…class1.cs…
private decimal? __att1;

So it declares it as a decimal (System.decimal) plus nullable! (using the ? sign NET 2.0 notation).

And the DDL file:
create table class1 (ID int identity not null, Att1 int null, primary key (ID))

Anyway, I think the main problem it is only with the class1.hbm.xml file.

Am I doing something wrong? this is my “first time” with decimal type in DBVA, so I do not test it properly.

Thanks for your info

Hello distansia,

Thank you for your post once again. I will check this with our developers and let you know their feedback.

Best regards,
Jick

Hi distansia,

The problem has been fixed. Please download and install the patch at:
http://files3.visual-paradigm.com/200711/Patch/sp1_20071116h/VP_Suite_Windows_3_1_sp1_20071116h.exe

Enjoy!

Best regards,
Jick

[quote=Jick]The problem has been fixed. Please download and install the patch at:
http://files3.visual-paradigm.com/200711/Patch/sp1_20071116h/VP_Suite_Windows_3_1_sp1_20071116h.exe

Enjoy![/quote]
Sure I will :stuck_out_tongue:

Many thanks again!!!

Hi Jick,

I am sorry but this one is not completely fixed, in case code is targeting the NET framework (C#, NHibernate).

Yes, now the mapping file shows:


<property ... type="Decimal" precision="19" scale="0" ... >

But in NHibernate, the precision and scale attributes are not in the XSD Schema, so they are not allowed.

As stated in NHibernate Documentation (section 16.1.1):

Many NHibernate mapping elements define an optional attribute named length. You may set the length of a column with this attribute. (Or, for numeric/decimal data types, the precision.)

So we can write:


<property ... type="Decimal" length="19" ... >

It works, but what about the scale?? We lost it!

Not at all, Sergey Koshcheyev (NHibernate main coder) says:

You can use type=“Decimal(precision, scale)” in the mapping files

Yes!! So, I tried with:


<property ... type="Decimal(19,0)" ... >

And all ok!! :smiley:

This is one of the little but annoying differences between Hibernate and NHibernate mapping files.

Anyway, good job fixing this. Works in ORM Persistable and ORM components too.

Hi distansia,

Thanks for the tips. I will check with our team to see if we can change @type by following your suggestions.

Best regards,
Jick

Hi distansia,

May I know more about your need of using precision? Normally NHibernate doesn’t care about the precision of a field. In other words, length and precision in XML does not affect the result. :? :?

Best regards,
Jick

Well, I am using a “decimal” type to store a “9999.9” number. So I use a Decimal(5,1) --> translated to SQL Server numeric(5,1).

The problem is that generated hbm.xml in NET does not correctly initialize NHibernate, because the “precision” and “scale” attributes are not defined in the mapping file NHibernate uses.

Yes, they are defined in Hibernate, so it must work with it. But not on .NET (C#, NHibernate).

The solution it is to change that behavior when generating for .NET and translate this attributes into the Decimal(x,y) notation.

I do not know if NHibernate will skip this altogether when dealing with data, but sure it do not initialize correctly :smiley:

And I can not use a “double” type to store that numeric value, because these are the requirements (Decimal with 9999.9 format).

I do not know if I explain myself :roll: Just ask me if in doubt

Thanks distansia,

I will tell our engineers about this.

Best regards,
Jick

Hi distansia,

I have talked to our engineers. We would like to know what did you mean by
"does not correctly initialize NHibernate"? What operation will fail if not to change decimal to decimal(19,0) in xml?

Best regards,
Jick

[quote=Jick]I have talked to our engineers. We would like to know what did you mean by
"does not correctly initialize NHibernate"? What operation will fail if not to change decimal to decimal(19,0) in xml?
[/quote]

Hi Jick,

I am not with Visual Studio right now, but I will send you the error message when I will be.

In the meanwhile, I remember something about “precission attribute not permitted” and “scale attribute not permitted”. I think there is no problem if type=“Decimal” and nothing else put. But I will report you.

Anyway, this can be easily tested with this line of code:
PersistentManager.Instance().GetSession().Close();

It throws a persistent exception.

(take care with the case, I can not test it with VS now)

Hi distansia,

Hmmm :? :? Decimal should be no problem. Please let me know your finding. Thank you.

Best regards,
Jick

Hi Jick,

Well my findings are:

  • If a Decimal field is inside a ORM Persistable class (and it is not a generalization), the hbm.xml generated is:
<property name="Number" column="Number" type="Decimal" not-null="false"/> 
  • If a Decimal field is inside a ORM Component class, the hbm.xml generated is:
<component name="comp1" class="pack1.comp1, Base" update="true" insert="true">
     <property name="Number" column="Number" type="Decimal" precision="19" scale="0" not-null="false" >
</component>
 
  • I forgot to test the case with a class being a generalization of another one (inheritance). You can test it if in doubt. I remember “joined-subclass” element had errors when generating code in previous builds.

The code needed to get the Component crazy :shock: sorry, I mean, to get the NHibernate error when initializing is:
BasePersistentManager.Instance().GetSession().Close();
(‘Base’ is the name of my project and assembly)

and the log4net log reports this error:

 
[544] ERROR NHibernate.Cfg.Configuration [(null)] - pack1.class1.hbm.xml(12,90): XML validation error: The 'precision' attribute is not declared.

BTW, I think it would be nice to be able to specify the decimal attributes in each case, not in general properties of the program. I mean, I have some decimal fields which are (5,1), other are (10,4), etc. Can I do this in the current build? To be honest I have not investigate this enough, and only found that general setting. So I manually change all definitions in DDL file before generating database.

Best regards

Hi distansia,

We’ll fix the problems and reply you shortly.

Best regards,
Jick

Hi Jick,

Sorry :oops: , I forgot to add that in this case:

[quote=distansia]- If a Decimal field is inside a ORM Persistable class (and it is not a generalization), the hbm.xml generated is:

<property name="Number" column="Number" type="Decimal" not-null="false"/> 

[/quote]

The generated code WORKS WELL. I mean, no persistent exception when initializing NHibernate. The problem is only when a decimal field is defined inside an ORM Component. Excuse me :wink:

Hi distansia,

As I know the problem occurs only in ORM Component and has been fixed. Please download the patch at:
http://files3.visual-paradigm.com/200711/Patch/sp1_20071119/VP_Suite_Windows_3_1_sp1_20071119.exe

Hope this helps!

Best regards,
Jick