0
votes

I'm new to NHibernate and am attempting to use Fluent's AutoMapping capability so that I do not need to maintain separate XML files by hand. Unfortunately I'm running into a problem with referenced entities, specifically 'Exception occurred getter of Fluent_NHibernate_Demo.Domain.Name.Id' - System.Reflection.TargetException: Object does not match target type.

I appear to have an error in at least one of my mapping classes although they do generate the correct SQL (i.e. the created tables have the correct indexes).

The implementations for my domain models and mappings are:


Name.cs

public class Name
{
    public virtual int Id { get; protected set; }
    public virtual string First { get; set; }
    public virtual string Middle { get; set; }
    public virtual string Last { get; set; }
}

Person.cs

public class Person
{
    public virtual int Id { get; protected set; }
    public virtual Name Name { get; set; }
    public virtual short Age { get; set; }
}

NameMap.cs

public NameMap()
{
    Table("`Name`");
    Id(x => x.Id).Column("`Id`").GeneratedBy.Identity();
    Map(x => x.First).Column("`First`").Not.Nullable().Length(20);
    Map(x => x.Middle).Column("`Middle`").Nullable().Length(20);
    Map(x => x.Last).Column("`Last`").Not.Nullable().Length(20);
}

PersonMap.cs

public PersonMap()
{
    Table("`Person`");
    Id(x => x.Id).Column("`Id`").GeneratedBy.Identity();
    References<Name>(x => x.Name.Id, "`NameId`").Not.Nullable();
    // There's no exception if the following line is used instead of References
    // although no constraint is created
    // Map(x => x.Name.Id).Column("`NameId`").Not.Nullable();
    Map(x => x.Age).Column("`Age`").Nullable();
}

Finally, the following code will produce the exception:

Name name = new Name { First = "John", Last = "Doe" };
session.Save(name);
Person person = new Person { Name = name, Age = 22 };
session.Save(person); // this line throws the exception

As mentioned, the created schema is correct but I'm unable to save using the above code. What is the correct way to create a foreign key constraint using Fluent NHibernate?

1

1 Answers

1
votes

If you want to reference the name, by ID, then that's what you should do. NHibernate is smart enough to figure out what the actual FK field on Person should be and where it should point; that is, after all, the job an ORM is designed to perform.

Try this mapping:

public PersonMap()
{
    Table("`Person`");
    Id(x => x.Id).Column("`Id`").GeneratedBy.Identity();
    References(x => x.Name, "`NameId`").Not.Nullable();        
    Map(x => x.Age).Column("`Age`").Nullable();
}

You've mapped the person and the name; as a result, NHibernate knows which property is the ID property of Name, and can create and traverse the foreign key on Person.