-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Trouble mapping a nullable Many-to-One relationship
PostPosted: Fri Nov 18, 2005 10:44 am 
Newbie

Joined: Tue Nov 01, 2005 6:32 pm
Posts: 16
This may not make a ton of sense because I may be using the incorrect ORM terms. I'm having trouble mapping a relationship where children can have either one or two parent objects.

Quick summary of the data model: Some customers have "business unit" entities, and these customers have their projects modeled thru these business units. Normal customers have a normal child collection of projects.

Image

(I personally think this relationship is confusing and not optimal but obviously I cannot change this, or else I wouldn't have a need for this question.)

My problem is mapping the project-business unit relationship bi-directionally.

Code:
<class name="Customer, AssemblyName" table="customer">
      <id name="Id" column="customer_id" unsaved-value="0">
         <generator class="assigned"/>
      </id>
      <property name="Name" column="Customer_name" type="String"/>
      <bag name="BusinessUnits" table="customer_business_unit" lazy="true" order-by="business_unit_name">
         <key column="customer_id"/>
         <one-to-many class="CustomerBusinessUnit, AssemblyName"/>
      </bag>      
      <bag name="Projects" table="project" lazy="true" order-by="project_name">
         <key column="customer_id"/>
         <one-to-many class="Project, AssemblyName"/>
      </bag>
   </class>


Code:
<class name="Project, AssemblyName" table="project">
      <id name="Id" column="project_id" unsaved-value="0">
         <generator class="assigned"/>
      </id>
      <property name="Name" column="Project_Name" type="String"/>
      <many-to-one name="ParentCustomer" class="Customer, AssemblyName"
               column="customer_id" />
      <many-to-one name="BusinessUnit" class="CustomerBusinessUnit, AssemblyName" insert="false" update="false" >
         <column name="customer_business_unit"/>
         <column name="customer_id"/>
      </many-to-one>
   </class>


Code:
<class name="CustomerBusinessUnit, AssemblyName" table="customer_business_unit">
      
      <composite-id>
         <key-property name="Id" column="business_unit_no"/>
         <key-many-to-one name="ParentCustomer" column="customer_id" class="Customer, AssemblyName"/>
      </composite-id>
      <property name="Name" column="business_unit_name" type="String"/>
      <bag name="Projects"  table="project" lazy="true" order-by="project_name">
         <key>
            <column name="customer_business_unit"/>
            <column name="customer_id"/>
         </key> 
         <many-to-many class="Project, AssemblyName" column="project_id" />
      </bag>
   </class>


I think the problem is further compounded by the fact that the original designers of the database gave the Customer_Business_Unit table a composite key of CustomerID and BusinessUnitNumber, rather than a unique key (i.e. customer id 755 has business unit #s 1, 2, 3; customer id 843 has business unit #s 1, 2, 3, 4, 5, etc.)

The <many-to-one> reference in the Project mapping to the CustomerBusinessUnit class works correctly for those projects that have both a parent customer and a parent business unit. However for (normal) projects no parent business unit, I get a UnresolvableObjectException:

Quote:
NHibernate.UnresolvableObjectException : No row with the given identifier exists: Advisor.CustomerBusinessUnit, of class: Advisor.CustomerBusinessUnit


From the logs, I can see that when NH materializes the Project object, a null value is returned for the customer_business_unit column of the project table. However, when resolving associations, instead of realizing that there is no ParentBusinessUnit for this Project object, it attempts to materialize a CustomerBusinessUnit with an identifier of the correct customer_id but a customer_business_unit of 0 (the default value of the integer property).

I'm really confused on how to correctly map this parent-optional parent-child relationship from the child project perspective. Can anyone be of any help? Am I using the wrong type of mapping in the Project class for the ParentBusinessUnit reference?


edit: One possible solution would be to remove the mapping from the Project hbm file all together, and change the ParentBusinessUnit getter to walk through the ParentCustomer.BusinessUnits collection, attempting to find one that contained the current object

Code:
public CustomerBusinessUnit BusinessUnit
      {
         get
         {
            Customer parent = this.ParentCustomer;

               CustomerBusinessUnit parentCbu = null;
               foreach (CustomerBusinessUnit cbu in parent.BusinessUnits)
               {
                  if (cbu.Projects.Contains(this))
                  {
                     parentCbu = cbu;
                     break;
                  }
               }
               return parentCbu;

         }
      }


but this is a lot slower and somehow feels dirty - I would much rather map this association directly from the database.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.