Hi, all!
Tonight I’ve found “interest” bug when played with NHibernate 1.0.1. Following situation was appeared:
I’ve developed following component class (in terms of NHibernate):
Code:
public struct Money
{
//...
public decimal Amount
{
get { return _amount; }
set { _amount = value; }
}
//...
And used it like following:
Code:
public class Account : DomainEntity
{
//...
public Money Balance
{
get { return _balance; }
set { _balance = value; }
}
//...
Following mapping enabled:
Code:
<hibernate-mapping >
<class ...>
...
<component name="Balance">
<property name="Amount" />
</component>
...
</class>
</hibernate-mapping>
And when I’ve performed simple list loading, the Amount property always was initialized with zero.
I’ve started to researching sources and have found this line:
this.getset.SetPropertyValues(component, values);
in the class ComponentType in method SetPropertyValues( object component, object[ ] values ) set target property (Amount) to nothing.
And later I’ve found the reason of this strange behavior:
Code has generated by the class GetSetHelperFactory in the method GenerateCode() do not make a differences between the value or reference type of mapped class.
My modifications which solve this bug you can see below:
Code:
private string GenerateCode()
{
StringBuilder sb = new StringBuilder();
sb.Append(header);
sb.AppendFormat(classDef, mappedClass.FullName.Replace('.', '_').Replace("+", "__"));
string componentAccessor = null;
if (!mappedClass.IsValueType)
{
componentAccessor = "t";
sb.AppendFormat(startSetMethod, mappedClass.FullName.Replace('+', '.'));
}
else
componentAccessor = String.Format("(({0})obj)", mappedClass.FullName.Replace('+', '.'));
for (int i = 0; i < setters.Length; i++)
{
ISetter setter = setters[i];
if (setter is BasicSetter && IsPublic(setter.PropertyName))
{
if (setter.Property.PropertyType.IsValueType)
{
sb.AppendFormat(
" {3}.{0} = values[{2}] == null ? new {1}() : ({1})values[{2}];\n",
setter.PropertyName,
setter.Property.PropertyType.FullName.Replace('+', '.'),
i, componentAccessor );
}
else
{
sb.AppendFormat(" {3}.{0} = ({1})values[{2}];\n",
setter.PropertyName,
setter.Property.PropertyType.FullName.Replace('+', '.'),
i, componentAccessor);
}
Regards