Hi,
I have what I think should be a fairly simple scenario:
I have Contacts, Companies and Clients. A Client can reference either a Contact or a Company.
Here are the classes:
public class Client { public virtual int Id { get; set; } public virtual string Code { get; set; } public virtual string Name { get; set; } public virtual int Status { get; set; } public virtual Company Company { get; set; } public virtual Contact Contact { get; set; } }
public class Company { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual Client Client { get; set; } }
public class Contact { public virtual int Id { get; set; } public virtual string FirstName { get; set; } public virtual string LastName { get; set; } public virtual Client Client { get; set; } }
and the corresponding conf:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="TestNH" namespace="TestNH.Domain">
<class name="Client"> <id name="Id" column="id"> <generator class="identity"></generator> </id> <property name="Code" column="code" type="string"/> <property name="Name" column="name" type="string"/> <property name="Status" column="status" type="int"/> <many-to-one name="Company" class="Company" column="companyId" unique="true" /> <many-to-one name="Contact" class="Contact" column="contactId" unique="true" /> </class>
<class name="Contact"> <id name="Id" column="id"> <generator class="identity"></generator> </id> <property name="FirstName" column="firstName" type="string"/> <property name="LastName" column="lastName" type="string"/> <one-to-one name="Client" class="Client" property-ref="Contact"/> </class>
<class name="Company"> <id name="Id" column="id"> <generator class="identity"></generator> </id> <property name="Name" column="name" type="string"/> <one-to-one name="Client" class="Client" property-ref="Company"/> </class>
</hibernate-mapping>
The database schema is pretty straightforward. The link between Client and Contact/Company is implemented through two foreign keys in the table Client: companyId and contactId.
Hi have two problems with this that I can't seem to solve.
1) The first one I can live with: A HQL query "from Contact" will load the Client with a bunch of SELECTs instead of doing a outer join, regardless of the value of the attribute "fetch" in the one-to-one relationship. The only way to do a join is if I explicitely do it in HQL like "from Contact c left join fetch c.Client"
2) The second one is more problematic: If I do the following query "from Client as c left join fetch c.Contact left join fetch c.Company", it will not only do a correct select on the Client table with two outer left joins on Contact and Company, but it will also generate one select per result on the Client table. Apparently it doesn't realise that it has already loaded the Client entity in the first select :
NHibernate: select top 20 client0_.id as id0_0_, contact1_.id as id1_1_, company2_.id as id2_2_, client0_.code as code0_0_, client0_.name as name0_0_, client0_.status as status0_0_, client0_.companyId as companyId0_0_, client0_.contactId as contactId0_0_, contact1_.firstName as firstName1_1_, contact1_.lastName as lastName1_1_, company2_.name as name2_2_ from Client client0_ left outer join Contact contact1_ on client0_.contactId=contact1_.id left outer join Company company2_ on client0_.companyId=company2_.id NHibernate: SELECT client0_.id as id0_0_, client0_.code as code0_0_, client0_.name as name0_0_, client0_.status as status0_0_, client0_.companyId as companyId0_0_, client0_.contactId as contactId0_0_ FROM Client client0_ WHERE client0_.companyId=@p0;@p0 = 1696 NHibernate: SELECT client0_.id as id0_0_, client0_.code as code0_0_, client0_.name as name0_0_, client0_.status as status0_0_, client0_.companyId as companyId0_0_, client0_.contactId as contactId0_0_ FROM Client client0_ WHERE client0_.contactId=@p0;@p0 = 248 etc....
Thanks for any pointer that can help me with that.
Blaise
|