-->
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.  [ 9 posts ] 
Author Message
 Post subject: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 4:49 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
I have 2 tables: countries and cities

country has an id(PK)
city has an id(PK) and a country(FK)

I use these mappings, but the foreign key isn't created in de db.
What do I do wrong?

Code:
   <class name="data.Country" table="countries">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>
   </class>

   <class name="data.City" table="cities">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <one-to-one name="country" class="data.Country" />
   </class>


And how do these relations work?

This is how I understand it:
one-to-one, one city has one country
one-to-many, one city has multiple countries
many-to-one, multiple cities can have the same country
many-to-many, multiple cities can have multiple countries

If I understand it right, country should have an one-to-many to cities and city should have an one-to-one to countries.
This doesn't make sence to me.

In SQL without hibernate I would give city a FK to country and problem solved.
Then the right query could get every combination.


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 5:48 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
As you properly state, multiple cities can have the same country,
so you should use many-to-one relation (in the mapping you report you use a one-to-one instead):

Code:
<class name="data.City" table="cities">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <many-to-one name="country" class="data.Country" />
   </class>


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 6:10 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Thanks for the reply.

Can you give an example of when to use one-to-one, because I don't really see the point of this?

And can I get the cities from country using the FK, so without adding another collection?
Or should I use a query for this?


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 6:28 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
Can you give an example of when to use one-to-one, because I don't really see the point of this?


Imagine a relation between a city and it's mayor.
A determinate city can have only one mayor.
A determinate mayor can be mayor of only one city.
That's a classical case of one-to-one
Quote:

And can I get the cities from country using the FK, so without adding another collection?

Not without a explicit query.
But consider that adding a collection on the country (=make the relation bidirectional) would not affect
the schema on database.

Quote:
Or should I use a query for this?


You can do also this. Personally, rather than writing a user query,
I always prefer do define the collection when I need to navigate in such direction, because the source-code becomes more simple
(on performance side there is no real difference because the implicit query by hibernate will be very similar to the one you would call manually).


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 6:31 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
So if I do this:
Country one-to-many City
City many-to-one Country

The DB would still be like:
Country: id(PK)
City: id(PK), country(FK)


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 6:34 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Yes, provided that you map it correctly as bidirectional relation (many-to-one side must be declared as owner).


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 7:02 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Thanks a lot, I've got these relations working.

I have one more relations I can't get to work.
I've been trying this one for almost two weeks, so I'd really appreciate it if you can help me with this one too.

I have the tables:
Country id(PK)
Language id(PK)
CountryName country(FK), language(FK), name

The CountryName is a join table to give each country multiple names.

At the moment I have the following, but it doesn't work.
Code:
   <class name="data.Country" table="countries">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <set name="countryNames" table="countryNames">
         <key column="country" />
         <one-to-many class="data.Country" />
      </set>
   </class>

   <class name="data.Language" table="languages">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <set name="countryNames" table="countryNames">
         <key column="language" />
         <one-to-many class="data.Language" />
      </set>
   </class>

   <class name="data.CountryName" table="countryNames">
      <composite-id name="fk" class="data.CountryNameFK">
         <key-many-to-one name="country" class="data.Country" column="country" />
         <key-many-to-one name="language" class="data.Language" column="language" />
      </composite-id>

      <property name="name" column="name" />
   </class>

In CountryName the key-many-to-one should be many-to-one FK's, but they should also be properties, else there not found by Hibernate.

If you could help me with this, you really are my hero of the week.


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 7:26 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi,

I'm not familiar with using composite-id as primary key because I never need it,
so I cant help you in this way.
But I want make you aware of another fact:
you are using natural id's as primary key which is an approach which I personally don't like because
it forces you to make your natural id's immutable.
With your approach for example you are not allowed to ever change the name of a country (especially if the concerning is already
assigned to cities) because then you would have constraints violations on the relative foreign keys.

For this reason I always prefer to use surrogate (generated) keys as primary key for all my entity classes
(therefore I never need composite-id's).
Natural keys such as country-name or language-code I define as normal properties
(eventually declaring it a natural id's and declaring a unique constraint on it, if needed)

In your scenario I simply would map CountryName with:
- a generated Identifier property
- a ManyToOne relation to Country
- a ManyToOne relation to Language
- define a additional (compound) unique-index on the fields country and language


Top
 Profile  
 
 Post subject: Re: One-to-one isn't created
PostPosted: Fri Mar 26, 2010 8:23 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Thanks a lot, it's finally working.


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