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.  [ 12 posts ] 
Author Message
 Post subject: One to Many mapping in Oracle with Sequences
PostPosted: Tue Oct 31, 2006 9:04 am 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
I have an Oracle database where I am trying to used NHibernat efor mappings (I am new to this so apologies if it sounds daft!)

I have two tables - Contacts and ContactDetails (The relationship being that one Contact can have many details).

There is an Oracle constraint on the ContactDetails table to ensure that a ContactId exists. Both tables have their primary keys generated by triggers reading from a sequence.

I can add new Contacts fine, I can update Contacts to show their attached details BUT I cannot create a new contact with details at the same time. I appreciate that the sequence used when creating the contact needs to then populate the constrained column in the details class before execution but, i thought this would be handled?

I continue to get an error advising that parent key not found i.e. from the constraint.

My mapping file looks as follows:

<class name="Wilson.NHibernate.Example.Contact,WilsonNHibernateExample" table="CONTACTS">
<id name="Id" column="CONTACTID" type="Int32" unsaved-value="0">
<generator class="assigned"/>
</id>
<discriminator column="ContactType" />
<property column="CONTACTNAME" type="String" name="Name" not-null="true" length="50" />
<component name="Address" class="Wilson.NHibernate.Example.Address, WilsonNHibernateExample" access="nosetter.camelcase">
<property column="ADDRESSLINE" type="String" name="Line" length="50" />
<property column="ADDRESSCITY" type="String" name="City" length="50" />
<property column="ADDRESSSTATE" type="String" name="State" length="2" />
<property column="ADDRESSZIP" type="String" name="Zip" length="5" />
</component>
<bag name="Details" cascade="all" access="nosetter.camelcase" lazy="true" inverse="true">
<key column="ContactId" />
<one-to-many class="Wilson.NHibernate.Example.Detail, WilsonNHibernateExample" />
</bag>
<subclass name="Wilson.NHibernate.Example.Person, WilsonNHibernateExample" discriminator-value="P" />
<subclass name="Wilson.NHibernate.Example.Business, WilsonNHibernateExample" discriminator-value="B">
<property name="Company" column="CompanyName" />
</subclass>

</class>
<class name="Wilson.NHibernate.Example.Detail,WilsonNHibernateExample" table="CONTACTDETAILS">
<id name="Id" column="DETAILID" type="Int32" unsaved-value="0">
<generator class="assigned"/>
</id>
<discriminator column="DetailType" />
<property column="DETAILINFO" type="String" name="Info" not-null="true" length="250" />
<property column="DETAILCOMMENT" type="String" name="Comment" length="250" />
<many-to-one name="Contact" column="ContactID" class="Wilson.NHibernate.Example.Contact, WilsonNHibernateExample" cascade="none" not-null="true" />
<subclass name="Wilson.NHibernate.Example.Phone, WilsonNHibernateExample" discriminator-value="P" />
<subclass name="Wilson.NHibernate.Example.Email, WilsonNHibernateExample" discriminator-value="E" />
</class>


I know that I have altered the ID's back to assigned but, even with Sequences this returned errors.

Can someone please confirm if this is possible?
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 31, 2006 10:49 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
First you definitely need to use the sequence ID's, not assigned.

Second are you setting the parent reference in the child object before save?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 31, 2006 11:30 am 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
I have changed to use the sequences - however, when you say set the parent id before save - is there any way to automatically pick this up when in the transaction.

E.g When I call the session.saveorupdate(this.contact) - can the mappings force the completion of the id knowing that the classes have a relationship?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 31, 2006 11:51 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Yes it happens automatically.

Don't set the ID... since it is a many to one you set the object

child.Parent = parent;


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 31, 2006 5:49 pm 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
Thanks for your help so far but, I think I may have messed things up a bit or got myself confused.

My Contacts Table has a PK of ContactID which is auto generated by a sequence called SEQ_TBLCONTACTS.

My ContactDetails table has a PK of DetailID which is auto generated by a sequence called SEQ_CONTACTDETAILS.

My contact class contains an IList of my details class. Therefore - there should be a one to many in my contact mapping and a many to one in my details mapping.

My understanding is that the ID in the mapping needs to be that of the PK fields i.e. with the sequence generator?

My mapping changes are as follows:


<class name="Wilson.NHibernate.Example.Contact,WilsonNHibernateExample" table="CONTACTS" >
<id name="Id" column="CONTACTID" type="Int32" unsaved-value="0" >
<generator class="sequence">
<param name ="sequence">seq_TBLCONTACTS</param>
</generator>
</id>
<discriminator column="ContactType" />
<property column="CONTACTNAME" type="String" name="Name" not-null="true" length="50" />
<component name="Address" class="Wilson.NHibernate.Example.Address, WilsonNHibernateExample" access="nosetter.camelcase">
<property column="ADDRESSLINE" type="String" name="Line" length="50" />
<property column="ADDRESSCITY" type="String" name="City" length="50" />
<property column="ADDRESSSTATE" type="String" name="State" length="2" />
<property column="ADDRESSZIP" type="String" name="Zip" length="5" />
</component>
<bag name="Details" cascade="all" >
<key column="ContactId" />
<one-to-many class="Wilson.NHibernate.Example.Detail, WilsonNHibernateExample" />
</bag>
<subclass name="Wilson.NHibernate.Example.Person, WilsonNHibernateExample" discriminator-value="P" />
<subclass name="Wilson.NHibernate.Example.Business, WilsonNHibernateExample" discriminator-value="B">
<property name="Company" column="CompanyName" />
</subclass>
</class>
<class name="Wilson.NHibernate.Example.Detail,WilsonNHibernateExample" table="CONTACTDETAILS">
<id name="Id" column="DetailID" type="Int32" unsaved-value="0">
<generator class="sequence">
<param name ="sequence">seq_CONTACTDETAILS</param>
</generator>
</id>


<discriminator column="DetailType" />
<property column="DETAILINFO" type="String" name="Info" not-null="true" length="250" />
<property column="DETAILCOMMENT" type="String" name="Comment" length="250" />
<many-to-one name="Contact" column="ContactID" class="Wilson.NHibernate.Example.Contact, WilsonNHibernateExample" cascade="all" not-null="true" />
<subclass name="Wilson.NHibernate.Example.Phone, WilsonNHibernateExample" discriminator-value="P" />
<subclass name="Wilson.NHibernate.Example.Email, WilsonNHibernateExample" discriminator-value="E" />
</class>

I really appreciate your help with this........I am anxious to see if I can get this to work.....

Cheers


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 31, 2006 6:00 pm 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
Sorry - should probablu have included the property within detail that sets parent property.......

public Contact Contact {
get { return this.contact; }
set {this.contact = value;
if (value != null) {
this.contactId = value.Id;
}
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 01, 2006 11:39 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
One thing that looks weird to me is why are you tracking the contactId as a seperate field in the ContactDetails object?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 02, 2006 4:14 am 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
The ContactID is the FK link back to the parent (contact object).....

I have another resolution which is to do with the trigger - the existing trigger has not been testing on the value being "not null" - therefore,
the sequence has been getting incremented when it shouldn't be.

I am still interested in your comment about tracking the ContactID - is my understanding of the relationship mappings correct?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 02, 2006 8:33 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
d.samuelson@btopenworld.c wrote:
The ContactID is the FK link back to the parent (contact object).....


No, the Contact object is the FK link back. That maps to the "many-to-one" mapping in your hbm file, which is correct.

You should not need a separate field for the contactId. Just reference "Contact.Id" to get that.

Depending on the scenario, NH may or may not be using your set accessor to set the Contact property. So if you were expecting contactId to be pouplated it may not be, but you don't need it anyway - just delete it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 02, 2006 11:21 am 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
Apologies - I didn't really appreciate it was the property in the Detail class you were referering to.........I assume this is what you mean?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 02, 2006 1:09 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Yes, the Contact property of the Details object. You don't need to store both the Contact and the Contact Id - get rid of the ID.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 03, 2006 4:41 am 
Newbie

Joined: Tue Oct 31, 2006 8:42 am
Posts: 12
Thanks for your help with this.....


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