4
votes

I have a problem which I can't solve. Maybe someone of you have encountered a similar problem.

I have two classes - Person and Contact and mapping to load all contacts for person. Those examples are all simplified for better reading.

Person.cs

public class Person
{
   public long Id { get; set; }
   public long ObjectId { get; set; }
   public IList<Contact> Contacts { get; set; }
}

Contact.cs

public class Contact
{
   public long Id { get; set; }
   public string Text { get; set; }
}

Person.hbm.xml

<property name="ObjectId" type="System.Int64" column="OBJECTID" />
<bag name="Contacts" lazy="true" cascade="all">
   <key column="PERSON_OBJECTID" property-ref="ObjectId" not-null="true" />
   <one-to-many class="Contact" />
</bag>

Contacts does not have any mapping for Persons, they just don't need it.

One person can have multiple contacts and one contact can have only one owner. But I create versions of persons when some of their data changes, because I need to keep history of changes. So tables look like this:

PERSONS TABLE

----------------------------------------
| ID | OBJECTID | FIRSTNAME | LASTNAME |
----------------------------------------
| 1  |    100   |   David   |   Gray   |
| 2  |    100   |   David   |   Gray   |
| 3  |    100   |   David   |   Gray   |
----------------------------------------

CONTACTS TABLE

--------------------------------------------
| ID | PERSON_OBJECTID |        TEXT       |
--------------------------------------------
| 1  |       100       | email@email.com   |
| 2  |       100       | some phonenumber  |
--------------------------------------------

I don't want to duplicate CONTACTS table rows each time a version is created for the PERSON - so I want to use ObjectId field instead which is always same for one person. This mapping successfully saves the data to database, but do not always retrieve it successfully. Sometimes I get error

Initializing[Person#100]-failed to lazily initialize a collection of role: Person.Contacts, no session or session was closed

In the error I can see that it shows me an #ObjectId, usually there's an #Id. Maybe there's some NHibernate bug related to that problem? That it's messes up property-ref property with primary key. Or is there some other way not to create another table (I can create a table where I hold persons Id and objectId)?.

If I map my tables with primary keys, then all works like a charm, but I get unwanted result - i must copy all contacts from previous version to current and in contacts table there's a huge amount of duplicate rows.

EDIT:

The SQL select clause sample for what I want to achieve is something like that:

select c.* from persons p
inner join contacts c on c.person_objectid = p.objectid
where p.id = 1;

So, can you help me please? :)

1
Did you manage to solve the issue?Alex M
No, unfortunately not.evilone

1 Answers

1
votes

There is a strange issue in NH assoicated with property-ref, you need, for some reason, even if it is not true, to add - unique="true" to the property-ref mappings.

try this in Person.hbm.xml -

<property name="ObjectId" type="System.Int64" column="OBJECTID" unique="true"/>