-->
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.  [ 7 posts ] 
Author Message
 Post subject: Problems reading info in complex table-per-subclass
PostPosted: Thu Aug 16, 2007 12:48 pm 
Newbie

Joined: Thu Aug 16, 2007 11:28 am
Posts: 4
Hi everybody,
I'm getting crazy trying to use NHibernate with a legacy database model.
The model is a very complex one, with multiple inheritances and references, and I'm mapping the database using the table-per-class strategy.

I have a main group of classes, which inheritance is defined in this tree:
Code:
OBJECT-ITEM
|
+---FACILITY (is a OBJECT-ITEM)
|   |
|   +--- ... some sub-facilities
|
+---... some other sub-object-items
|
+---ORGANISATION (is a OBJECT-ITEM)
     |
     +---UNIT (is a ORGANISATION)
     |
     +---CONVOY (is a ORGANISATION)


The C# implementation of the main object tree is:
Code:
    public class ObjectItem: DaoBasic {
        private System.Double id= 0;
        virtual public System.Double Id {
            get { return id;  }
        }
        private string objectItemCategoryCode= null;
        virtual public string ObjectItemCategoryCode {
            get { return objectItemCategoryCode; }
            set { objectItemCategoryCode = value; }
        }
        private System.String objectItemName= null;
        virtual public System.String ObjectItemName {
            get { return objectItemName;  }
            set { objectItemName = value;  }
        }
        private System.String objectItemAlternateIdentificationText= null;
        virtual public System.String ObjectItemAlternateIdentificationText {
            get { return objectItemAlternateIdentificationText;  }
            set { objectItemAlternateIdentificationText = value;  }
        }
        private System.Double ownerId= 0;
        virtual public System.Double OwnerId {
            get { return ownerId;  }
            set { ownerId = value;  }
        }
        private string updateSeqnr= null;
        virtual public string UpdateSeqnr {
            get { return updateSeqnr;  }
            set { updateSeqnr = value;  }
        }
    }
    public class Facility: ObjectItem {
        // Implementation of facility
    }
    // Many other classes definition inheriting from ObjectItem
    public class Organisation: ObjectItem {
        private string organisationCategoryCode= null;
        virtual public string OrganisationCategoryCode {
            get { return organisationCategoryCode; }
            set { organisationCategoryCode = value; }
        }
        private System.String organisationNicknameName= null;
        virtual public System.String OrganisationNicknameName {
            get { return organisationNicknameName;  }
            set { organisationNicknameName = value;  }
        }
        private System.Double ownerId= 0;
        virtual public new System.Double OwnerId {
            get { return ownerId;  }
            set { ownerId = value;  }
        }
        private string updateSeqnr= null;
        virtual public new string UpdateSeqnr {
            get { return updateSeqnr;  }
            set { updateSeqnr = value;  }
        }
    }
    public class Unit: Organisation {
        private System.String unitFormalAbbreviatedName= null;
        [DatamodelMap("unit-formal-abbreviated-name")]
        virtual public System.String UnitFormalAbbreviatedName {
            get { return unitFormalAbbreviatedName;  }
            set { unitFormalAbbreviatedName = value;  }
        }
        private System.Double ownerId= 0;
        virtual public new System.Double OwnerId {
            get { return ownerId;  }
            set { ownerId = value;  }
        }
        private string updateSeqnr= null;
        virtual public new string UpdateSeqnr {
            get { return updateSeqnr;  }
            set { updateSeqnr = value;  }
        }
    }
    public class Convoy: Organisation {
        // And so on...
    }


Mapping of the main object tree:
Code:
    <class name="ObjectItem" table="OBJ_ITEM">
        <id name="id" column="obj_item_id" access="field">
            <generator class="increment" />
        </id>
        <property name="objectItemCategoryCode" column="cat_code" access="field" />
        <property name="objectItemName" column="name" access="field" />
        <property name="objectItemAlternateIdentificationText" column="altn_identific_txt" access="field" />
        <property name="ownerId" column="owner_id" access="field" />
        <property name="updateSeqnr" column="update_seqnr" access="field" />
        <joined-subclass name="Facility" table="FAC">
            <key column="fac_id" />
            <!-- mapping of FACILITY -->
        </joined-subclass>
        <!-- mapping of other sub-classes -->
        <joined-subclass name="Organisation" table="ORG">
            <key column="org_id" />
            <property name="organisationCategoryCode" column="cat_code" access="field" />
            <property name="organisationNicknameName" column="nickname_name" access="field" />
            <property name="ownerId" column="owner_id" access="field" />
            <property name="updateSeqnr" column="update_seqnr" access="field" />
            <joined-subclass name="Unit" table="UNIT">
                <key column="unit_id" />
                <property name="unitFormalAbbreviatedName" column="formal_abbrd_name" access="field" />
                <property name="ownerId" column="owner_id" access="field" />
                <property name="updateSeqnr" column="update_seqnr" access="field" />
            </joined-subclass>
            <joined-subclass name="Convoy" table="CONVOY">
                <key column="convoy_id" />
                <property name="convoyDaySpeedRate" column="day_speed_rate" access="field" />
                <property name="convoyDayVehicleGapDimension" column="day_vehicle_gap_dim" access="field" />
                <property name="convoyHaltDuration" column="halt_dur" access="field" />
                <property name="convoyNightSpeedRate" column="night_speed_rate" access="field" />
                <property name="convoyNightVehicleGapDimension" column="night_vehicle_gap_dim" access="field" />
                <property name="convoyPacketGapDimension" column="packet_gap_dim" access="field" />
                <property name="convoyPacketSizeQuantity" column="packet_size_qty" access="field" />
                <property name="ownerId" column="owner_id" access="field" />
                <property name="updateSeqnr" column="update_seqnr" access="field" />
            </joined-subclass>
        </joined-subclass>
    </class>


First problem:
It is possible to do
Code:
    System.Collections.IList list = session.CreateCriteria().List(typeof(ObjectItem));

This is possible too
Code:
    System.Collections.IList list = session.CreateCriteria().List(typeof(Unit)); // Subclass of Organisation

But there is an exception here!
Code:
    System.Collections.IList list = session.CreateCriteria().List(typeof(Organisation)); // Subclass of ObjectItem


Second Problem:
So far it would't be a big issue because it could be possible to query using the root class, but unfortunately there are some
other classes which have a foreign-key to ORGANISATION objects.
For example, the class definition is
Code:
    public class ReportingData: DaoBasic {
        private System.Double id= 0;
        virtual public System.Double Id {
            get { return id;  }
        }
        private System.String reportingDataReportingDate= null;
        virtual public System.String ReportingDataReportingDate {
            get { return reportingDataReportingDate;  }
            set { reportingDataReportingDate = value;  }
        }
        private System.String reportingDataReportingTime= null;
        virtual public System.String ReportingDataReportingTime {
            get { return reportingDataReportingTime;  }
            set { reportingDataReportingTime = value;  }
        }
        private string reportingDataSourceTypeCode= null;
        virtual public string ReportingDataSourceTypeCode {
            get { return reportingDataSourceTypeCode; }
            set { reportingDataSourceTypeCode = value; }
        }
        private System.Double ownerId= 0;
        virtual public System.Double OwnerId {
            get { return ownerId;  }
            set { ownerId = value;  }
        }
        private string updateSeqnr= null;
        virtual public string UpdateSeqnr {
            get { return updateSeqnr;  }
            set { updateSeqnr = value;  }
        }
        // ... Some other members ...
        private Organisation reportingDataReportingOrganisationId= null;
        virtual public Organisation ReportingDataReportingOrganisationId {
            get { return reportingDataReportingOrganisationId;  }
            set { reportingDataReportingOrganisationId = value;  }
        }
    }

And the map file
Code:
    <class name="ReportingData" table="RPTD">
        <id name="id" column="rptd_id" access="field">
            <generator class="increment" />
        </id>
        <property name="reportingDataReportingDate" column="rep_date" access="field" />
        <property name="reportingDataReportingTime" column="rep_time" access="field" />
        <property name="ownerId" column="owner_id" access="field" />
        <property name="updateSeqnr" column="update_seqnr" access="field" />
        <!-- some other properties -->
        <many-to-one name="reportingDataReportingOrganisationId" class="Organisation" column="rep_org_id" access="field" />
    </class>


In this case, when accessing the Organisation field inside a ReportingData object, the same (or very similar) exception is thrown.
The text description of the exception is:
could not load an entity: [CCIS.Database.Dao.C2iedm.Organisation#270010000000210][SQL: SELECT organisati0_.org_id as obj1_21_0_, organisati0_.cat_code as cat2_44_0_, organisati0_.nickname_name as nickname3_44_0_, organisati0_.owner_id as owner4_44_0_, organisati0_.update_seqnr as update5_44_0_, organisati0_1_.cat_code as cat2_21_0_, organisati0_1_.name as name21_0_, organisati0_1_.altn_identific_txt as altn4_21_0_, organisati0_1_.owner_id as owner5_21_0_, organisati0_1_.update_seqnr as update6_21_0_, organisati0_2_.formal_abbrd_name as formal2_45_0_, organisati0_2_.owner_id as owner3_45_0_, organisati0_2_.update_seqnr as update4_45_0_, organisati0_3_.day_speed_rate as day2_46_0_, organisati0_3_.day_vehicle_gap_dim as day3_46_0_, organisati0_3_.halt_dur as halt4_46_0_, organisati0_3_.night_speed_rate as night5_46_0_, organisati0_3_.night_vehicle_gap_dim as night6_46_0_, organisati0_3_.packet_gap_dim as packet7_46_0_, organisati0_3_.packet_size_qty as packet8_46_0_, organisati0_3_.owner_id as owner9_46_0_, organisati0_3_.update_seqnr as update10_46_0_, decode (, organisati0_2_.unit_id, 24, organisati0_3_.convoy_id, 25, organisati0_.org_id, 23,0 ) as clazz_0_ FROM ORG organisati0_, OBJ_ITEM organisati0_1_, UNIT organisati0_2_, CONVOY organisati0_3_ WHERE organisati0_.org_id=organisati0_1_.obj_item_id and organisati0_.org_id=organisati0_2_.unit_id(+) and organisati0_.org_id=organisati0_3_.convoy_id(+) AND organisati0_.org_id=?]

Obviously the SQL code generated has an error at decode (,

Hibernate version:
NHibernate 1.2.0.GA
Code between sessionFactory.openSession() and session.close():
if (sessionFactory != null) {
ISession session = sessionFactory.OpenSession();
System.Collections.IList list = session.CreateCriteria(typeof(ReportingData)).List();
foreach (object o in list) {
Inform("Object: {0}\r\n", o.ToString());
}
session.Close();
session.Dispose();
}
Name and version of the database you are using:
Oracle 10
The generated SQL (show_sql=true):
See Exception description

Does anybody know a solution to this problem?
Thank you in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 8:02 pm 
Newbie

Joined: Thu Aug 16, 2007 7:55 pm
Posts: 3
I'm having some issues with polymorphic queries also. I also have a nested joined-subclass and but do not get the wrong sql but instead the following error:

System.IndexOutOfRangeException: Unable to find specified column in result set
at Oracle.DataAccess.Client.OracleDataReader.GetOrdinal(String name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)


Should we report this bug in jira? Perhaps the version from the trunk fixes it?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 8:09 pm 
Newbie

Joined: Thu Aug 16, 2007 7:55 pm
Posts: 3
aykito, I think the problem you're having does not occur in version 2.0 alpha of NHiberate (which is the version I'm running now) - the decode is correct in the sql. But I'm having another issue which I haven't figure it out (can even be my mistake somewhere in the mapping..)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 8:44 pm 
Newbie

Joined: Thu Aug 16, 2007 7:55 pm
Posts: 3
Really seems like a bug: for some reason NHibernate is expecting "clazz_0_" in the Loader class at:

if (persister.HasSubclasses)
{
// code to handle subclasses of topClass
object discriminatorValue = persister.DiscriminatorType.NullSafeGet(
rs, EntityAliases[i].SuffixedDiscriminatorAlias, session, null);

...


Trying to figure it out. Does any one have a hint? thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 17, 2007 4:12 am 
Newbie

Joined: Thu Aug 16, 2007 11:28 am
Posts: 4
Pedro thank you very much for your help, I'm new with NHibernate and I didn't know if this issue would be a problem with my code or a simple concept misunderstanding.
I'm going to try with newer versions, I'll post here my results.


Top
 Profile  
 
 Post subject: Not better with the NHibernate 2.0 Alpha
PostPosted: Tue Aug 21, 2007 6:41 am 
Newbie

Joined: Thu Aug 16, 2007 11:28 am
Posts: 4
Well I've downloaded and compiled the last version in the repository [NHibernate Alpha 2.0.0. Alpha 1], and the results are even worse.

Now when trying to read objects mapped to one single table (without polymorphism) I have no problem, but will all the polymorphic objects there are exceptions, for example:

ADOException, text message:
Code:
could not execute query
[ SELECT this_.rptd_id as rptd1_10_0_, this_.acc_code as acc2_10_0_, this_.cat_code as cat3_10_0_, this_.cntg_ind_code as cntg4_10_0_, this_.credibility_code as credibil5_10_0_, this_.reliability_code as reliabil6_10_0_, this_.rep_date as rep7_10_0_, this_.rep_time as rep8_10_0_, this_.source_type_code as source9_10_0_, this_.timing_cat_code as timing10_10_0_, this_.ent_cat_code as ent11_10_0_, this_.owner_id as owner12_10_0_, this_.update_seqnr as update13_10_0_, this_.ref_id as ref14_10_0_, this_.rep_org_id as rep15_10_0_, this_1_.offset_dur as offset2_11_0_, this_1_.owner_id as owner3_11_0_, this_1_.update_seqnr as update4_11_0_, this_1_.ref_act_task_id as ref5_11_0_, this_2_.effctv_start_date as effctv2_12_0_, this_2_.effctv_start_time as effctv3_12_0_, this_2_.effctv_end_date as effctv4_12_0_, this_2_.effctv_end_time as effctv5_12_0_, this_2_.owner_id as owner6_12_0_, this_2_.update_seqnr as update7_12_0_, decode(this_.rptd_id, this_1_.rptd_rel_timing_rptd_id, 1, this_2_.rptd_abs_timing_rptd_id, 2, 0) FROM RPTD this_, RPTD_REL_TIMING this_1_, RPTD_ABS_TIMING this_2_ WHERE this_.rptd_id=this_1_.rptd_rel_timing_rptd_id(+) and this_.rptd_id=this_2_.rptd_abs_timing_rptd_id(+) ]
[SQL: SELECT this_.rptd_id as rptd1_10_0_, this_.acc_code as acc2_10_0_, this_.cat_code as cat3_10_0_, this_.cntg_ind_code as cntg4_10_0_, this_.credibility_code as credibil5_10_0_, this_.reliability_code as reliabil6_10_0_, this_.rep_date as rep7_10_0_, this_.rep_time as rep8_10_0_, this_.source_type_code as source9_10_0_, this_.timing_cat_code as timing10_10_0_, this_.ent_cat_code as ent11_10_0_, this_.owner_id as owner12_10_0_, this_.update_seqnr as update13_10_0_, this_.ref_id as ref14_10_0_, this_.rep_org_id as rep15_10_0_, this_1_.offset_dur as offset2_11_0_, this_1_.owner_id as owner3_11_0_, this_1_.update_seqnr as update4_11_0_, this_1_.ref_act_task_id as ref5_11_0_, this_2_.effctv_start_date as effctv2_12_0_, this_2_.effctv_start_time as effctv3_12_0_, this_2_.effctv_end_date as effctv4_12_0_, this_2_.effctv_end_time as effctv5_12_0_, this_2_.owner_id as owner6_12_0_, this_2_.update_seqnr as update7_12_0_, decode(this_.rptd_id, this_1_.rptd_rel_timing_rptd_id, 1, this_2_.rptd_abs_timing_rptd_id, 2, 0) FROM RPTD this_, RPTD_REL_TIMING this_1_, RPTD_ABS_TIMING this_2_ WHERE this_.rptd_id=this_1_.rptd_rel_timing_rptd_id(+) and this_.rptd_id=this_2_.rptd_abs_timing_rptd_id(+)]


Its inner exception is
System.IndexOutOfRangeException, text message:
Code:
clazz_0_


By the way, I forgot to write down the configuration file, maybe the problem is here:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="CCIS.Database.Dao.NHibernate.Manager.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
    </configSections>
    <applicationSettings>
        <CCIS.Database.Dao.NHibernate.Manager.Properties.Settings>
            <setting name="Test" serializeAs="String">
                <value>Test</value>
            </setting>
        </CCIS.Database.Dao.NHibernate.Manager.Properties.Settings>
    </applicationSettings>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
            <property name="dialect">NHibernate.Dialect.OracleDialect</property>
            <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
            <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
            <property name="connection.connection_string">Data Source=ora10pe;User ID=c2iedm;Password=c2iedm</property>
        </session-factory>
    </hibernate-configuration>
</configuration>


So I guess the alpha version is not yet stable, and the rest of the problem a bug NHibernate 1.4.


Top
 Profile  
 
 Post subject: Its working with Oracle9Dialect
PostPosted: Wed Aug 22, 2007 3:52 am 
Newbie

Joined: Thu Aug 16, 2007 11:28 am
Posts: 4
Hi all again,

Coming back to NHibernate 1.2 I've changed the dialect to Oracle9Dialect (instead of OracleDialect) in the configuration file:
Code:
...
            <property name="dialect">NHibernate.Dialect.Oracle9Dialect</property>
...

instead of
Code:
...
            <property name="dialect">NHibernate.Dialect.OracleDialect</property>
...

And now I can do also
Code:
            System.Collections.IList list = session.CreateCriteria(typeof(Organisation)).List();

at last without exceptions.

Threfore this seems to be a bug, probably in the frame of the OracleDialect class.
And this is a question for the administrators: shall I report it? Shall you do it?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.