-->
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.  [ 2 posts ] 
Author Message
 Post subject: Explicit polymorphism and inheritence mapping
PostPosted: Wed Dec 20, 2006 3:13 am 
Newbie

Joined: Wed Dec 20, 2006 2:52 am
Posts: 2
I am having issues assigning a reference to a subclass, for a joined-subclass mapped class. Basically, I can never cast it from a superclass reference. What is the recommended practice for using joined-subclass mapping classes polymorphically, if I cannot use the as or is operators?

Below follows a description of the issue:

In some test code, I am modelling a financial transaction, involving a financial security. To this effect, I have a Transaction class, and it has a Security property.

Now, a Security can either be a generic Security, or a more specific Option, which inherits from Security. I have a joined-subclass mapping in my Security.hbm.xml for Option.

The schema for Securities is two tables, Security and Option. Option has a foreign key SecurityId that maps to the Id column in the Security table.

The problem is that NHibernate retrieves the Transaction object and it's contained Security but, in the second line below, always returns null for a cast to Option, even if the Security is in fact an Option...

Code:
...
// Create an Option, assign to Transaction object, and SaveAndPersist.
...
IList<Transaction> trans = FindAll<Transaction>();
Option option = trans[0].Security as Option; // option is always inexplicably null
...

public ReadOnlyCollection<T> FindAll<T>(params ICriterion[] criterions)
{
    ICriteria criteria = _session.CreateCriteria(typeof (T));
    foreach (ICriterion criterion in criterions)
    {
        criteria.Add(criterion);
    }
    List<T> list = new List<T>();
    foreach (object o in criteria.List())
        list.Add((T) o);

    return list.AsReadOnly();
}


The problem is that NHibernate wraps the Security object in its proxy class, in this case of type CProxyTypeNextWorks_DomainModel_Security_NHibernate_ProxyINHibernateProxy1. Now, as the base class of the proxy is Security, this proxy is obviously fine to assign to the Transaction.Security property, but I cannot ever cast this back to an Option. In the Watch panel in Visual Studio 2005, I can see that the value of the Security is an Option, but I cannot cast to an option because of the Proxy wrapping (or so I believe).

I have run SQL Profiler and NHibernate is joining the tables correctly in the query.

What is the recommended practice for using joined-subclass mapping classes polymorphically, if I cannot use the as or is operators?

Version and mapping documents below.

Hibernate version:
1.2.0.2002

Mapping documents:
Code:
Security
=========
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NextWorks.DomainModel" namespace="NextWorks.DomainModel"
                   default-access="field.camelcase-underscore">

  <class name="Security" table="Security">

    <id name="ID" column="id" type="Int32" unsaved-value="0" access="field.lowercase-underscore">
      <generator class="identity" />
    </id>

   <property name="Name" />
    
    <many-to-one name="StockExchange" class="NextWorks.DomainModel.StockExchange" column="StockExchangeID"
        not-null="true"/>
   
    <bag name="Transactions"
         inverse="true">

        <key column="SecurityID"/>
        <one-to-many class="Transaction"/>
    </bag>

  </class>

  <joined-subclass name="Option" table="Option" extends="NextWorks.DomainModel.Security">

     <key column="SecurityId" />
     <property name="Type" />
     <property name="MaturityDate" />
     <property name="ExercisePrice" />
     <property name="ContractSize" />

  </joined-subclass>
</hibernate-mapping>



Code:
Transaction
===========
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NextWorks.DomainModel" namespace="NextWorks.DomainModel"
                   default-access="field.camelcase-underscore">
   
  <class name="Transaction" table="Transaction">
    <id name="ID" column="id" type="Int32" unsaved-value="0" access="field.lowercase-underscore">
      <generator class="identity" />
    </id>
     
    <property name="ProcessingDate"  />
    <property name="Type" />
    <property name="Quantity" />
    <property name="BrokerFee" />
    <property name="ClearingFee" />
    <property name="CommissionFee" />
    <property name="TransactionPrice" />
   <property name="TransactionDate" access="field.camelcase-underscore" />
   <property name="EffectiveValue" access="field.camelcase-underscore" />

    <many-to-one name="Security" class="Security" column="SecurityID"
         not-null="true"/>

    <many-to-one name="Account" class="Account" column="AccountID"
         not-null="true" />
   
    <many-to-one name="Currency" class="NextWorks.DomainModel.Currency" column="CurrencyID"
         not-null="true" />
   
  </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 7:43 pm 
Newbie

Joined: Wed Dec 20, 2006 2:52 am
Posts: 2
A long time since I posted this, found the answer so I thought I should follow up.

The problem was that the property was lazy loading, so I was trying to cast it before it loaded properly - in short, I was trying to cast a proxy that hadn't yet been filled.


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

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.