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.  [ 4 posts ] 
Author Message
 Post subject: Mapping Question
PostPosted: Tue Apr 01, 2008 8:09 pm 
Newbie

Joined: Tue Apr 01, 2008 4:16 pm
Posts: 6
I'm trying to figure how to do the mapping for this or if it is even possible. I have a many-to-many relationship between two tables (for simplicity's sake I've reduced the tables down to pertinent information):

Code:
CREATE TABLE Person (
    PersonId int identity(1,1) NOT NULL
        CONSTRAINT PK_PERSON_PERSONID PRIMARY KEY,
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL
)


Code:
CREATE TABLE Address (
    AddressId int identity(1,1) NOT NULL
        CONSTRAINT PK_ADDRESS_ADDRESSID PRIMARY KEY,
    Line1 varchar(50) NOT NULL
)


The addresses are linked to the Person via a link table:

Code:
CREATE TABLE PersonAddress (
    PersonAddressId int identity(1,1) NOT NULL
        CONSTRAINT PK_PERSONADDRESS_PERSONADDRESSID PRIMARY KEY,
    PersonId int NOT NULL
   CONSTRAINT FK_PERSONADDRESS_PERSONID FOREIGN KEY REFERENCES Person (PersonId),
    AddressId int NOT NULL
   CONSTRAINT FK_PERSONADDRESS_ADDRESSID FOREIGN KEY REFERENCES Address (AddressId),
    ContactDescriptionId int NULL
   CONSTRAINT FK_PERSONADDRESS_CONTACTDESCRIPTIONID FOREIGN KEY REFERENCES ContactDescription (ContactDescriptionId))


The Contact Description table is just a simple lookup table:

Code:
CREATE TABLE ContactDescription (
    ContactDescriptionId int identity(1,1) NOT NULL
        CONSTRAINT PK_CONTACTDESCRIPTION_CONTACTDESCRIPTIONID PRIMARY KEY,
    Description varchar(30) NOT NULL
)


My question is, when using a many-to-many relationship between Person and Address, I would like to attach the contact description class as a property of the Address. This is done because the addresses are reused in relation to other tables (for instance there is a DivisionAddress link table, etc) so the contact description for a specific address might be one thing when linked to Person A but might be completely different when the same address is linked to Division A.

Here are the mappings I am currently using:

Code:
  <class name="Person" table="Person">
    <id name="Id">
      <column name="PersonId" sql-type="Int32" not-null="true"/>
      <generator class="native" />
    </id>
    <property name="LastName" />
    <property name="FirstName" />
    <bag name="AddressEntries" lazy="true" cascade="all"  table="PersonAddress">
      <key column="PersonId"/>
      <many-to-many class="Address" column="AddressId" />
    </bag>
  </class>


Code:
  <class name="Address" table="Address">
    <id name="Id">
      <column name="AddressId" sql-type="Int32" not-null="true"/>
      <generator class="native" />
    </id>
    <property name="Line1" />
  </class>


Can this be done? If so how would the mapping for it work. Thanks.


Top
 Profile  
 
 Post subject: Mapping Question
PostPosted: Wed Apr 02, 2008 4:31 am 
Senior
Senior

Joined: Thu Jun 21, 2007 8:03 am
Posts: 127
Location: UK
Hi Crolis,

If you want extra information in your link table, the you probably want an intermediate link class and two one-to-many relationships. I don't think the contact description is a property of an Address, since it cannot be determined from an AddressId on its own.

This is also suggested in the best practices (last point on the list):
http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/best-practices.html

Regards,
Richard


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 03, 2008 10:09 pm 
Newbie

Joined: Tue Apr 01, 2008 4:16 pm
Posts: 6
I've been killing myself for awhile now. I've changed it to use an intermediate link class but now I'm banging my head up against a brick wall.

Here are my mappings:

Code:
  <class name="Person" table="Person">
    <id name="Id">
      <column name="PersonId" sql-type="Int32" not-null="true"/>
      <generator class="identity" />
    </id>
    <property name="LastName" />
    <property name="FirstName" />
    <set name="AddressEntries" cascade="all-delete-orphan" inverse="true" generic="true" lazy="false">
      <key column="PersonId"/>
      <one-to-many class="AddressLink" />
    </set>
  </class>


Code:
  <class name="AddressLink" table="PersonAddress">
    <id name="Id">
      <column name="PersonAddressId" sql-type="Int32" not-null="true"/>
      <generator class="identity" />
    </id>
    <many-to-one name="Person" column="PersonId" class="Person" not-null="true"/>
    <many-to-one name="Address" column="AddressId" cascade="all" class="Address"/>
    <many-to-one name="ContactDescription" column="ContactDescriptionId" class="ContactDescription"/>
    <many-to-one name="Status" column="Status" class="Status"/>
  </class>


No matter what I do, it tries to put NULL into the PersonId field in the DB in the PersonAddress table. Everything else works perfectly but that one-to-many relationship refuses to work. I changed the PersonId field to allow NULLs just to see and then when I look in the db, all the fields are correct except for the PersonId field in the PersonAddress table which is NULL. Ofcourse this breaks the relationship so it won't load the AddressLink objects when loading a Person.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 03, 2008 11:42 pm 
Newbie

Joined: Tue Apr 01, 2008 4:16 pm
Posts: 6
Finally figured it out. When I was adding the Link to the collection, I was not setting the Person in the Link object to "this".


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.