-->
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.  [ 8 posts ] 
Author Message
 Post subject: Composite-id consists of 2 Foreign Key's
PostPosted: Tue Apr 13, 2010 8:40 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
I have another thread with the same problem, but I'm trying a different solution. Therefor this thread.
The other: viewtopic.php?f=1&t=1003721

Situation: I have 3 classes. Country, Language and CountryName
Country and Language have an id (assigned) and some unrelevant stuff.
CountryName has a many-to-one to Country, a many-to-one to Language and a name (String).

The problem is in CountryName. The two many-to-one's are used as a composite key, so I've tried to map them as a composite id. But I'm still unlucky.

Can someone help me with this problem or give me a example of a similar (working) structure?

Note: I'm confident the problem is in the mapping of CountryNames, but I've added the entire code.

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

      <set name="countryNames" table="countryNames" inverse="true" cascade="delete">
         <key column="country" />
         <one-to-many class="data.CountryName" />
      </set>
   </class>
Code:
   <class name="data.Language" table="languages">
      <id name="id" column="id" length="31">
         <generator class="assigned" />
      </id>

      <set name="countryNames" table="countryNames" inverse="true" cascade="delete">
         <key column="language" />
         <one-to-many class="data.CountryName" />
      </set>
   </class>
Code:
   <class name="data.CountryName" table="countryNames">
      <composite-id name="countryLanguageFK" class="data.CountryLanguageFK">
         <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>
These are my java classes:
Code:
public class Country
{
   private String id;
   private Set<CountryName> countryNames = new HashSet<CountryName>(0);
   
   public Country()
   {
      
   }
   
   /* Getters */
   public String getId()
   {
      return id;
   }
   
   public Set<CountryName> getCountryNames()
   {
      return countryNames;
   }
   
   /* Setters */
   private void setId(String id)
   {
      this.id = id;
   }
   
   public void setCountryNames(Set<CountryName> countryNames)
   {
      this.countryNames = countryNames;
   }
}
Code:
public class Language
{
   private String id;
   private Set<CountryName> countryNames = new HashSet<CountryName>(0);
   
   public Language()
   {
      
   }
   
   /* Getters */
   public String getId()
   {
      return id;
   }
   
   public Set<CountryName> getCountryNames()
   {
      return countryNames;
   }
   
   /* Setters */
   private void setId(String id)
   {
      this.id = id;
   }
   
   public void setCountryNames(Set<CountryName> countryNames)
   {
      this.countryNames = countryNames;
   }
}
Code:
public class CountryName
{
   private CountryLanguageFK countryLanguageFK;
   private String name;
   
   public CountryName()
   {
      
   }
   
   /* Getters */
   public CountryLanguageFK getCountryLanguageFK()
   {
      return countryLanguageFK;
   }
   
   public Country getCountry()
   {
      return countryLanguageFK.getCountry();
   }
   
   public Language getLanguage()
   {
      return countryLanguageFK.getLanguage();
   }
   
   public String getName()
   {
      return name;
   }
   
   /* Setters */
   public void setCountryLanguageFK(CountryLanguageFK countryLanguageFK)
   {
      this.countryLanguageFK = countryLanguageFK;
   }
   
   public void setCountry(Country country)
   {
      countryLanguageFK.setCountry(country);
   }
   
   public void setLanguage(Language language)
   {
      countryLanguageFK.setLanguage(language);
   }
   
   public void setName(String name)
   {
      this.name = name;
   }
}

class CountryLanguageFK implements Serializable
{
   private Country country;
   private Language language;
   
   public CountryLanguageFK(Country country, Language language)
   {
      this.country = country;
      this.language = language;
   }
   
   public Country getCountry()
   {
      return country;
   }
   
   public Language getLanguage()
   {
      return language;
   }
   
   public void setCountry(Country country)
   {
      this.country = country;
   }
   
   public void setLanguage(Language language)
   {
      this.language = language;
   }
   
   /* Override */
   public boolean equals(Object o)
   {
      if (o instanceof CountryLanguageFK)
      {
         CountryLanguageFK other = (CountryLanguageFK) o;
         return new EqualsBuilder().append(country, other.getCountry()).append(language, other.getLanguage()).isEquals();
      }
      else
         return false;
   }
   
   public int hashCode()
   {
      return new HashCodeBuilder().append(country).append(language).toHashCode();
   }
}
And this is the error I receive:
Code:
org.hibernate.QueryException: could not resolve property: country of: data.CountryName
   at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67)
   at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:61)
   at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1402)
   at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:54)
   at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1377)
   at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:457)
   at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:417)
   at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:68)
   at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:357)
   at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:113)
   at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82)
   at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:91)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1577)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
   at main.HibernateMain.main(HibernateMain.java:27)


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Tue Apr 13, 2010 11:42 am 
Regular
Regular

Joined: Mon Jan 05, 2009 6:42 pm
Posts: 99
Location: IL
I think this is a situation of Many-to-Many case. I think below is what is there in your mind and i'm just re-iterating.
a given Country can speak multiple Languages and the Given Language can be Spoken in Multiple Countries.
Code:
Country
CountryId   Name
1               Canada
2               France

Language

languageId Name
10              French
20              English

CountryLanguage

countryId     languageId
1                 10
1                 20
2                 10



So I guess look for any many-to-many implementations and you should be good to go.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Tue Apr 13, 2010 12:18 pm 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Almost.

I use it for the names of the countries in different languages.

For example England could be translated to:
Engeland, Angleterre, Inglaterra
(Dutch, French, Spanisch)

But this is just one example. I have many classes which are structured like this.

A many-to-many relation would need additional properties which can't be done.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Tue Apr 13, 2010 1:31 pm 
Regular
Regular

Joined: Mon Jan 05, 2009 6:42 pm
Posts: 99
Location: IL
Hi- Thanks for your explanation. Its more convoluted than I originally thought. Also Sorry-i'm not resolving the issue i'm only posting this how this domain might look like if I were to do. Again please use advices with caution ;-)

This is not typical Many-to-Many.
A given country might be pronounced or Alias differently in Different languages.
A given Language can pronounce or Alias different Countries differently.
Also a Given Country might be Pronounced the Same way even in different languages.

Country
CountryId Name
1 Canada
2 France
3 England

Alias
AliasId Alias
100 a(sorry lack of better example or knowledge)
200 b
300 c

Language
languageId Language
10 Dutch
20 French
30 Spanish

CountryAlias

CountryId AliasId LanguageId
1 100 10
1 100 20

1 200 30
2 300 10

So the entity Country will have List and NOT Set of Aliases as each alias can point to a different language.
And the entity Language will have Set of Alias and each alias points to different country.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Tue Apr 13, 2010 1:45 pm 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
I think you understand my problem, but I find my explanation easier.

Can someone help me?
It's hard to believe no one else has used a structure like this.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Fri Apr 16, 2010 6:01 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
Can someone help me?

If the situation is unclear, I can give another example.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Wed Sep 22, 2010 8:25 pm 
Beginner
Beginner

Joined: Fri Mar 11, 2005 7:46 am
Posts: 29
Hi aukemid - I'm having a similar issue - did you find a way to trick hibernate? thx.


Top
 Profile  
 
 Post subject: Re: Composite-id consists of 2 Foreign Key's
PostPosted: Wed Oct 06, 2010 5:46 am 
Regular
Regular

Joined: Wed Mar 10, 2010 4:48 am
Posts: 106
I didn't find the solution I wanted but I did get it working.

CountryName has it's own id (assigned) and the two many-to-one's which need to be unique together:
Code:
<class name="data.CountryName" table="countryNames">
        <id name="id" column="id" length="31">
            <generator class="assigned" />
        </id>

        <properties name="countryLanguageUnique" unique="true">
            <many-to-one name="country" class="data.Country" column="country" not-null="true" />
            <many-to-one name="language" class="data.Language" column="language" not-null="true" />
        </properties>
        <property name="name" column="name" />
    </class>


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