Class file issue in 1 --> n relationship - what am I missing?

Aug 29, 2010 at 1:16 AM

Hello,

I am using the 1.0 mapping generator (.NET 3.5) and I have two database tables (Oracle 10g) as follows:

CREATE TABLE  "RPT_SOURCE" 
   (	"SOURCE_ID" NUMBER(10,0) NOT NULL ENABLE, 
	"GROUP_ID" NUMBER(10,0) NOT NULL ENABLE, 
	"NAME" NVARCHAR2(50) NOT NULL ENABLE, 
	"BODY" BLOB, 
	"SOURCE_PATH" NVARCHAR2(200), 
	 CONSTRAINT "RPT_SOURCE_PK" PRIMARY KEY ("SOURCE_ID") ENABLE, 
	 CONSTRAINT "RPT_SOURCE_FK" FOREIGN KEY ("GROUP_ID")
	  REFERENCES  "RPT_SOURCE_GROUP" ("GROUP_ID") ON DELETE CASCADE ENABLE
   )

CREATE TABLE  "RPT_SOURCE_GROUP" 
   (	"GROUP_ID" NUMBER(10,0) NOT NULL ENABLE, 
	"NAME" NVARCHAR2(50) NOT NULL ENABLE, 
	"COUNTRY" NVARCHAR2(40), 
	"YEAR" NUMBER(4,0) NOT NULL ENABLE, 
	"ASSET" NVARCHAR2(40), 
	"FRN" NVARCHAR2(20), 
	"MEDIA_TYPE" NVARCHAR2(40), 
	"ANNOTATION" NVARCHAR2(2000), 
	"STATUS" NVARCHAR2(20) NOT NULL ENABLE, 
	"CREATED" DATE NOT NULL ENABLE, 
	 CONSTRAINT "RPT_SOURCE_GROUP_PK" PRIMARY KEY ("GROUP_ID") ENABLE
   )

You can see that the RPT_SOURCE table has a foreign key constraint with a reference to the RPT_SOURCE_GROUP table.  This is a one-to-many relationship.
When I open the mapping generator and connect to the DB, I see both tables in the picklist along with the sequences.  When I generate the files, however, the
resulting .cs class files do no show a hint of any relationship.  The following are the two class file definitions:
namespace FirstSample.Domain {
    
    public class RPT_SOURCE {
        public RPT_SOURCE() {
        }
        public virtual byte[] body { get; set; }
        public virtual long groupId { get; set; }
        public virtual string name { get; set; }
        public virtual long sourceId { get; set; }
        public virtual string sourcePath { get; set; }
    }
}
namespace FirstSample.Domain {
    
    public class RPT_SOURCE_GROUP {
        public RPT_SOURCE_GROUP() {
        }
        public virtual string annotation { get; set; }
        public virtual string asset { get; set; }
        public virtual string country { get; set; }
        public virtual System.DateTime created { get; set; }
        public virtual string frn { get; set; }
        public virtual long groupId { get; set; }
        public virtual string mediaType { get; set; }
        public virtual string name { get; set; }
        public virtual string status { get; set; }
        public virtual long year { get; set; }
    }
}
You can see there is no hint of any RPT_SOURCE object (some array) in the RPT_SOURCE_GROUP object.  I must be missing how to deal with 1-to-many
relationships because I don't see any way that such a tool could be of use if it didn't.
Can anyone shed any light as to what I am missing?
Thanks for your time - Peter
Developer
Aug 29, 2010 at 1:38 AM
Edited Aug 29, 2010 at 1:44 AM

In RPT_SOURCE_GROUP, you have to add `public virtual IList<RPT_SOURCE> rptSources`, I believe in order to tell NH about the has-many relationship. I suspect also that your *.hbm.xml file will also be wrong.

I'm currently working on the next beta release and with the DDL you provided, my version produced the following mapping.

 

    public class RptSource {
        public RptSource() { }
        public virtual long SourceId { get; set; }
        public virtual RptSourceGroup RptSourceGroup { get; set; }
        public virtual string Name { get; set; }
        public virtual byte[] Body { get; set; }
        public virtual string SourcePath { get; set; }
    }
    public class RptSourceGroup {
        public RptSourceGroup() { }
        public virtual long GroupId { get; set; }
        public virtual IList<RptSource> RptSources { get; set; }
        public virtual string Name { get; set; }
        public virtual string Country { get; set; }
        public virtual long Year { get; set; }
        public virtual string Asset { get; set; }
        public virtual string Frn { get; set; }
        public virtual string MediaType { get; set; }
        public virtual string Annotation { get; set; }
        public virtual string Status { get; set; }
        public virtual System.DateTime Created { get; set; }
    }

 

Aug 29, 2010 at 3:05 AM

Thanks for the reply.  The hbm.xml file for the two look like (not sure what they should look like from the v2.0 perspective):

<hibernate-mapping assembly="FirstSample" xmlns="urn:nhibernate-mapping-2.2">
  <class name="FirstSample.Domain.RptSourceGroup, FirstSample" table="RPT_SOURCE_GROUP" lazy="true" >
    <id name="groupId" type="Int64" column="GROUP_ID">
      <generator class="sequence">
        <param name="sequence">RPT_SOURCE_SEQ</param>
      </generator>
    </id>
    <property name="annotation" column="ANNOTATION" />
    <property name="asset" column="ASSET" />
    <property name="country" column="COUNTRY" />
    <property name="created" column="CREATED" />
    <property name="frn" column="FRN" />
    <property name="mediaType" column="MEDIA_TYPE" />
    <property name="name" column="NAME" />
    <property name="status" column="STATUS" />
    <property name="year" column="YEAR" />
  </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="FirstSample" xmlns="urn:nhibernate-mapping-2.2">
  <class name="FirstSample.Domain.RptSource, FirstSample" table="RPT_SOURCE" lazy="true" >
    <id name="sourceId" type="Int64" column="SOURCE_ID">
      <generator class="sequence">
        <param name="sequence">RPT_SOURCE_SEQ</param>
      </generator>
    </id>
    <property name="body" column="BODY" />
    <property name="groupId" column="GROUP_ID" />
    <property name="name" column="NAME" />
    <property name="sourcePath" column="SOURCE_PATH" />
  </class>
</hibernate-mapping>

 So is the Beta version you are working on right now the v2.0 Beta1?  My concern is that I believe that version is only for .NET 4.0 and I am using .NET 3.5.  Will that version work with .NET 3.5?  In any case, this is a good news / bads news thing.

The good news is that I know that the v1.0 version that I am using simply didn't handle those situations and I can stop hunting around.  The bad news is I don't think it will be safe for me to fudge the .cs and hbm.xml files

to try to get it to work as I could easily mess things up.  If the v2.0 Beta 1 will work with my .NET 3.0, then maybe I could go that route and upgrade as that goes to a stable version.  What are your thoughts?

One last thing now that you mention v1.0 wasn't handling something.  I had another posting (http://groups.google.com/group/nhusers/browse_thread/thread/7df22d6a776a2f04) where I had some odd behavior

concerning auto-generated primary keys from sequences.  If you get a second, can you see if that is something v2.0 will fix?

Thanks for your time and help - Peter

Aug 30, 2010 at 4:28 PM

I just installed the 2.0 Beta 1 but found out that I could not launch it because it requires .NET 4.0.  We are using .NET 3.5 and can't upgrade at the moment.  Are theer any other altrernatives to getting the 2.0 enhancements working in our 3.5 environment?

Thanks - Peter

Aug 31, 2010 at 1:48 PM

lengtche,

I installed .NET 4 and then the latest v2.0 Beta 1 from the web site.  When I ran it on my database schema, however, I seem to get the same results as I did with the v1.0.  I do not see the new enhancements that you listed concerning the one-to-many relationships.  Were you running a Beta version which is not up ont he site as of yet??  Also, one other question.. In your example that you listed above, you listed the class names in the generated files as "public class RptSource {" and "public class RptSourceGroup {".  How did you get the values to appear like that, as my generated files get the class names RPT_SOURCE and RPT_SOURCE_GROUP.

Thanks - Peter

Aug 31, 2010 at 2:36 PM

Okay, I just saw that your latest version (v2.0 Beta2) was just added today.  I installed that one and that answerd my two questions from the above posting.  I see two potential issues and will post those as forum questions individually but will give the general issue here:

1) The list of database tables to choose from looks like it probably came from the all_tables table rather than the user_tables table.  The difference is well over 1000 extra database table references.  This makes it very timeconsuming to find the user table you are looking for.

2) The hbm.xml mapping file did not seem to identify how the primary key will be populated.  I will run some tests to see exactly what happens before posting.

Thansk - Peter

Developer
Aug 31, 2010 at 4:11 PM

Please post the HBM mapping and let me know what you would have expected and I can investigate from there. :)

Aug 31, 2010 at 4:43 PM

In v2.0 beta 1, when I selected my table, the sequence associatd with the table would appear int he sequence picklist.  When the sequence was selected, the hbm.xml file would define the primary key like:

<id name="GroupId" type="Int64" column="GROUP_ID">
      <generator class="sequence">
        <param name="sequence">RPT_SOURCE_SEQ</param>
      </generator>
</id>

 

In v2.0 beta 2, the sequence does not appear and so when the hbm.xml file is generated, the primary key definition looks like:

<id name="GroupId" column="GROUP_ID" />

I think it would be the same if the sequence was available to pick.  Not sure why the sequences are not showing up now but may be related to the change to where the table names are retrieved.

- Peter