Problem trying to set property type by reflection

1,908 views
Skip to first unread message

niberhate

unread,
Jan 18, 2010, 7:22:29 PM1/18/10
to nhusers
I had put this mistakenly in the development group and was asked to
ask in this group. So here it goes.

I am playing with the HelloNHibernate example of NHibernate In
Action. The source code can be downloaded from
http://www.manning.com/kuate/NHibernateInAction.Source.zip

You will find an example solution called "1. Simple Example - Helllo
NHibernate" in that zip package.

Because the objective of that example is to have the minimum working
solution of NHibernate, it has public fields instead of private. The
fields are Id, Name and Manager (I use PascalStyle for naming
convention, so I capitalized the initial characters of these fields.)

So, I changed the public fields into public auto properties, and then
the following method throws and exception at c.AddAssembly
(Assembly.GetCallingAssembly());

static ISession OpenSession()
{
if (factory == null)
{
Configuration c = new Configuration();
c.AddAssembly(Assembly.GetCallingAssembly());
factory = c.BuildSessionFactory();
}
return factory.OpenSession();
}

The exception says:

{"Could not compile the mapping document:
HelloNHibernate.HelloNHibernate.Employee.hbm.xml"}

And the inner exception says:

{"Problem trying to set property type by reflection"}

In other words, everything else being the same, the following works:

namespace HelloNHibernate
{
class Employee
{
public int Id;
public string Name;
public Employee Manager;

public string SayHello()
{
return string.Format(
"'Hello World!', said {0}.", Name);
}
}
}


Whereas the following fails:

namespace HelloNHibernate
{
class Employee
{
public int Id { get; private set; }
public string Name { get; set; }
public Employee Manager { get; set; }

public string SayHello()
{
return string.Format(
"'Hello World!', said {0}.", Name);
}
}
}

What is the caveat? Does NHibernate have any special configuration
requirement for auto properties to work? Any idea? Thanks.

devonl

unread,
Jan 19, 2010, 2:23:15 PM1/19/10
to nhusers
In that example, the mapping file is telling NH to set the Id property
using the field (in this case "id") You have a private accessor in the
Id property, and you are not declaring a private field behind it "id"
so NH doesn't know how to set that "Id" property.

You need to tell NH how to access that property when it builds the
proxy. Check here for the specific documentation:

http://nhforge.org/doc/nh/en/index.html#mapping-declaration-property

In your example, the easiest solution would probably be to make that
private setter protected. That way the proxy will inherit the ability
to set the value of Id.

Also, I took a look at that tutorial and it really sets up some poor
practices (public lowercase fields, for one). Try this one instead:

http://nhforge.org/doc/nh/en/index.html#quickstart-intro

hth,

-devon

On Jan 18, 4:22 pm, niberhate <gnewsgr...@gmail.com> wrote:
> I had put this mistakenly in the development group and was asked to
> ask in this group.  So here it goes.
>
> I am playing with the HelloNHibernate example of NHibernate In

> Action.  The source code can be downloaded fromhttp://www.manning.com/kuate/NHibernateInAction.Source.zip

niberhate

unread,
Jan 20, 2010, 6:04:38 PM1/20/10
to nhusers
Hi, Devon, thanks a lot for your response.

One of the authors of NHibernate in Action has told me that in order
to auto properties of C#, we must also remove access="field" in the
mapping XML file, which is piece of new info that can be found
nowhere.

I did try to use auto properties because I don't like their public
fields. Lowercase is probably fine.

Reply all
Reply to author
Forward
0 new messages