views:

23

answers:

1

I have a User, some of which are an employee. This is a one-to-one relationship and not all users are employees.

When I get a user it doesn't seem to be bring back the employee information it just has it marked as null. I thought I have got my head around nhibernate but I have tried playing with so many properties on the mapping files and haven't got it working. Any ideas or pointers as to what I am doing incorrect?

User Class:

public class User
    {
        public virtual int UserID { get; set; }
        public virtual string Username { get; set; }
        public virtual string Title { get; set; }
        public virtual string Forename { get; set; }
        public virtual string Surname { get; set; }

        public virtual Employee Employee { get; set; }
    }

User Mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Portal.Core"
                   namespace="Portal.Core.Data.Database">

  <class name="User" table="[Users]">
    <id name="UserID">
      <generator class="identity" />
    </id>
    <property name="Username" not-null="true" length="50" />
    <property name="Title" length="10" />
    <property name="Forename" length="50" />
    <property name="Surname" length="50" />

    <one-to-one name="Employee" class="Employee" fetch="select" lazy="false" foreign-key="EmployeeID" />


  </class>

</hibernate-mapping>

Employee Class:

public class Employee
    {
        public virtual int EmployeeID { get; set; }
        public virtual string RoomNumber { get; set; }
        public virtual string JobTitle { get; set; }
        public virtual User User { get; set; }
    }

Employee Mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Portal.Core"
                   namespace="Portal.Core.Data.Database">

  <class name="Employee" table="[Employees]">
    <id name="EmployeeID">
      <generator class="identity" />
    </id>
    <many-to-one name="User" unique="true" column="UserID" class="User" fetch="select" foreign-key="UserID" ></many-to-one>

    <property name="RoomNumber" length="20" />
    <property name="JobTitle" length="20" />

  </class>

</hibernate-mapping>
+1  A: 

The only thing I can see is different from Ayende's example is that you specify a foreign-key tag. Maybe try stripping your mapping down to Ayende's example (Which by the way is the exact same scenario) and try adding the extra properties/attributes one by one?

Goblin
Have tried his example. It is half working now in that if i create a new user and add an employee record to it, it works fine. When I try and merge two users together (update employee record to be attached to new user) it just seems to lose the link. NHibernate is so hard to debug :/
Andi
You are breaking the 'rules' when you do it like this - when you tell NHibernate that this is a one-one relationship - you are not allowed to let one end of the association shift to another end-point. Instead you should update or create the employee-record for the user that will remain after your operation.
Goblin
To clarify - it sounds like your case isn't really a one-one relationship, but rather a compoenent.
Goblin
+1 for help but how would I move an employee record to the new user then without breaking ties that employee record had in the system?
Andi
Also this article implies if the employee has its own table component can't be used? Do you know any more about this? Thank you! http://stackoverflow.com/questions/541649/is-it-one-to-one-or-component-nhibernate-mapping
Andi
@Andi: If you want to keep the one-to-one: You just copy the values to the staying user's employee-record (or new it, if it doesn't exist). That way you don't 'break' the rules as the original employee-record is either deleted with the deleted user-record or continues it's association with that one. About the component cannot be used: It is correct that component mapping can only work if data is in the same table - I don't know if you can update the schema?
Goblin
I could update the schema but not everyone is an employee so makes sense for it to be a seperate table. Only problem with copying values over is anything linked to the old employee ID will break. Seems like a bit of an issue with nHibernate if you can't update a record in this way...
Andi
Actually, it is more that you don't want it to work like a 'real' one-to-one because you let the Id's shift. Thus, You need to handle the cascading yourself - in other words - it's not an issue with nHibernate, but rather that you are working against the idea of one-to-one. If I were you (and I'm not), I'd forget the notion of one-to-one and go with a many-to-one instead - and then manually enforce that only one user at a time can point to the same employee-record.
Goblin