-->
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.  [ 10 posts ] 
Author Message
 Post subject: Composite identifiers and one-to-one relationships
PostPosted: Thu Mar 27, 2008 11:56 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Could anyone suggest how I should map the following. I have two tables, Clients and Freightpayers which map to a Client class and a Freightpayer class respectively. The tables are linked in a one-to-one relationship, sharing the same primary keys. In each case the key consists of two columns, Prefix char(2) and ID int. These map to a value class of type DBKey in the application. In the client table, ID is an identity (*) and in the Freightpayer the key is assigned to match the Client.

My question is, is there a way to map the above such that I get the same behaviour I'd get for single column keys, using the generator=foreign attribute for the freightpayer? The composite-id element doesn't have a generator attribute so I can't set it directly.


(*) the identity in the Client composite-id is not a problem. I've written a customer persister, along with a couple of (very) small mods to the nhibernate sources to support it.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 5:16 am 
Beginner
Beginner

Joined: Fri Aug 10, 2007 3:34 am
Posts: 44
a solution would be to use a id of a custom user type and assign it
using the "assigned" generator class

something like this
<id type="compositeType">
<generator class="assigned"/>
</id>

and make sure you assign this id immediately after you save

the custom user type should be a combination of the two types

i don't know if this will help, it's just an intuition...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 5:52 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Matrasinator wrote:
a solution would be to use a id of a custom user type


I thought that was what I was currently doing to be honest, though with a different mapping than the one you gave:

Code:
<class name="Saturn.DAO.Domain.Freightpayer, Saturn.DAO" table="FreightPayers">
    <composite-id name="ID" class="Saturn.DAO.Types.DBKey">
      <key-property name="Prefix"/>
      <key-property name="ID"/>
    </composite-id>


Can you point me at some info on the mapping you provided, if it's different?

I was really hoping to get away from manually assigning the key. I feel I should be able to set the Client property of the Freightpayer and the key would be set.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 6:00 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Specifically, it's this part of the documentation I'm struggling with when it comes to composite ids:

Quote:
Now we must ensure that the primary keys of related rows in the PERSON and EMPLOYEE tables are equal.
We use a special NHibernate identifier generation strategy called foreign:

Code:
<class name="Person" table="PERSON">
<id name="Id" column="PERSON_ID">
<generator class="foreign">
<param name="property">Employee</param>
</generator>
</id>
...
<one-to-one name="Employee"
class="Employee"
constrained="true"/>
</class>

Quote:
A newly saved instance of Person is then assigned the same primar key value as the Employee instance refered
with the Employee property of that Person.


I'm not sure how to specify the equivalent of "foreign" for a composite-id


Top
 Profile  
 
 Post subject: Composite identifiers and one-to-one relationships
PostPosted: Fri Mar 28, 2008 6:29 am 
Senior
Senior

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

I'm not sure if this is the situation you are asking about, but the documentation states that you can only use 'assigned' identifier when they are composite:

http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/components.html#components-compositeid

Quote:
You can't use an IIdentifierGenerator to generate composite keys. Instead the application must assign its own identifiers.


Regards,
Richard


Top
 Profile  
 
 Post subject: Re: Composite identifiers and one-to-one relationships
PostPosted: Fri Mar 28, 2008 6:35 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
FlukeFan wrote:
You can't use an IIdentifierGenerator to generate composite keys. Instead the application must assign its own identifiers.


Hi Richard,

Ah, I was aware of that issue with regards to identities (in fact I've written a new persister which overcomes this, and lets a composite key use generated IDs), but I didn't realise it applied to foreign key relationships as well. Are you sure of the above, out of interest? I can see that setting the Client property of the Freightpayer is analagous to assigning the identifier anyway, so I wonder if it might be different.

Kev


Top
 Profile  
 
 Post subject: Composite identifiers and one-to-one relationships
PostPosted: Fri Mar 28, 2008 6:57 am 
Senior
Senior

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

The docs also say:

Quote:
Now, any foreign keys into the table FOOS are also composite. You must declare this in your mappings for other classes.


Quote:
Are you sure of the above, out of interest?

Um ... not 100% to be fair ... maybe 67.3%? :-)

Quote:
I can see that setting the Client property of the Freightpayer is analagous to assigning the identifier anyway ...

Agreed. Another option might be to simply ignore the 'setting' of IDs. For example:
Code:
class Freightpayer
...
    public DBKey Id
    {
        get { return Client.Id; }
        set { // do nothing, handled by setting the Client property }
    }
...   


Regards,
Richard


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 11:02 am 
Beginner
Beginner

Joined: Fri Aug 10, 2007 3:34 am
Posts: 44
you should try not to use composite-key mapping, it's nasty and
it's not a 'best practice'


Top
 Profile  
 
 Post subject: Re: Composite identifiers and one-to-one relationships
PostPosted: Fri Mar 28, 2008 11:09 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Quote:
Now, any foreign keys into the table FOOS are also composite. You must declare this in your mappings for other classes.


Yes, I'm happy with that, and that side of it all seems to work. I guess largely I'm thinking from an aesthetic (?!) point of view that having to set both the Client property and the ID seems ugly, and that there's enough metadata there for NHibernate to be able to do it itself.

Quote:
Agreed. Another option might be to simply ignore the 'setting' of IDs. For example:


Ah, now that's an interesting idea - i'll take a look at where it gets me.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 28, 2008 11:15 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Matrasinator wrote:
you should try not to use composite-key mapping, it's nasty and
it's not a 'best practice'


Ah, would that it were so easy. Unfortunately this is a legacy application. The database runs to a few hundred tables, and contains in the region of 2000 stored procedures. We need to rewrite the front end in such a way that both it and the existing front end can coexist during the transition period. If I could do away with the composite keys without breaking anything I'd do it like a shot, but it's not an option

Kev


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