-->
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.  [ 5 posts ] 
Author Message
 Post subject: One-to-one relationship with composite primary key
PostPosted: Sat Feb 13, 2010 9:19 pm 
Newbie

Joined: Sat Feb 13, 2010 9:08 pm
Posts: 3
I am trying to establish a one-to-one relationship between Product and Translation entity classes.

Product attributes:
- sku (pk)
- manuf (pk)
- catalog (pk)
- (Product attrs)

Translation attributes:
- sku (pk,fk)
- manuf (pk,fk)
- catalog (pk,fk)
- (Translation attrs)

I have a hibernate mapping similar to the following for Product:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 12, 2010 9:46:14 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
  <class catalog="myapp" name="myapp.Product" table="Products">
    <composite-id class="myapp.ProductId" name="id">
      <key-property name="sku" type="string">
        <column length="128" name="sku"/>
      </key-property>
      <key-property name="manuf" type="int">
        <column name="manuf"/>
      </key-property>
      <key-property name="catalog" type="string">
        <column length="128" name="catalog"/>
      </key-property>
    </composite-id>

    <one-to-one name="translation" class="myapp.Translation" />

  </class>
</hibernate-mapping>


For Translation:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 12, 2010 9:46:14 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
  <class catalog="myapp" name="myapp.Translation" table="Translations">
    <composite-id class="myapp.TranslationId" name="id">
      <key-property name="sku" type="string">
        <column length="128" name="sku"/>
      </key-property>
      <key-property name="manuf" type="int">
        <column name="manuf"/>
      </key-property>
      <key-property name="catalog" type="string">
        <column length="128" name="catalog"/>
      </key-property>
    </composite-id>
  </class>
</hibernate-mapping>


The ProductId and TranslationId hbm.xml files are not shown but I can post them if it would help.

However, when I call product.getTranslation() I get this error:

Code:
attr: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class myapp.TranslationId, got class myapp.ProductId


What am I doing wrong?


Top
 Profile  
 
 Post subject: Re: One-to-one relationship with composite primary key
PostPosted: Sun Feb 14, 2010 1:08 am 
Newbie

Joined: Sat Feb 13, 2010 9:08 pm
Posts: 3
I found this bug report which indicates that Hibernate requires classes that share a composite key to use the same composite identifier class in one-to-one relationships.

Modifying the Translation class and .hbm.xml file to use the ProductId class instead of TranslationId class solved the problem.

I'm not sure if this is a bug or a feature.


Top
 Profile  
 
 Post subject: Re: One-to-one relationship with composite primary key
PostPosted: Sun Feb 14, 2010 5:57 am 
Beginner
Beginner

Joined: Wed Nov 21, 2007 8:02 am
Posts: 48
you have to add 'constrained="true"' as an attribute to your one to one mapping and move the foreign key constraints to product table


Top
 Profile  
 
 Post subject: Re: One-to-one relationship with composite primary key
PostPosted: Mon Feb 15, 2010 2:42 pm 
Newbie

Joined: Sat Feb 13, 2010 9:08 pm
Posts: 3
kavithakaran wrote:
you have to add 'constrained="true"' as an attribute to your one to one mapping and move the foreign key constraints to product table


I'm not sure how to do that. Could you please give an example?


Top
 Profile  
 
 Post subject: Re: One-to-one relationship with composite primary key
PostPosted: Mon Feb 15, 2010 6:36 pm 
Beginner
Beginner

Joined: Wed Nov 21, 2007 8:02 am
Posts: 48
I failed to spot another mistake. Since you are sharing the primary key between the two tables, you need only one Id class.. ie. ProductId class only..

Here is the complete solution
Code:
package myapp;

public class Product {
   private ProductId id;

   public ProductId getId() {
      return id;
   }

   public void setId(ProductId id) {
      this.id = id;
   }

   public Translation getTranslation() {
      return translation;
   }

   public void setTranslation(Translation translation) {
      this.translation = translation;
   }

   private Translation translation;
}


Code:
package myapp;

public class Translation {
   private ProductId id;
   private String description;

   public ProductId getId() {
      return id;
   }

   public void setId(ProductId id) {
      this.id = id;
   }

   public String getDescription() {
      return description;
   }

   public void setDescription(String description) {
      this.description = description;
   }
}


Code:
package myapp;

import java.io.Serializable;

public class ProductId implements Serializable {
   private static final long serialVersionUID = 1L;
   private String sku;
   private int manuf;

   private String catalog;

   public String getSku() {
      return sku;
   }

   public void setSku(String sku) {
      this.sku = sku;
   }

   public int getManuf() {
      return manuf;
   }

   public void setManuf(int manuf) {
      this.manuf = manuf;
   }

   public String getCatalog() {
      return catalog;
   }

   public void setCatalog(String catalog) {
      this.catalog = catalog;
   }

   public boolean equals(Object other) {
      if (other == null)
         return false;
      if (!this.getClass().equals(other.getClass()))
         return false;
      ProductId otherId = (ProductId) other;
      if (this.catalog.equals(otherId.catalog) && this.manuf == otherId.manuf
            && this.sku.equals(otherId.sku)) {
         return true;
      } else
         return false;
   }
   
   public int hashCode() {
        int result;
        result = catalog.hashCode();
        result = 29 * result + manuf;
        result = 29 * result + sku.hashCode();
        return result;
    }

}

<hibernate-mapping>
<class name="myapp.Product" table="Products">
<composite-id class="myapp.ProductId" name="id">
<key-property name="sku" type="string">
<column length="128" name="sku"/>
</key-property>
<key-property name="manuf" type="int">
<column name="manuf"/>
</key-property>
<key-property name="catalog" type="string">
<column length="128" name="catalog"/>
</key-property>
</composite-id>
<one-to-one name="translation" constrained="true" class="myapp.Translation" cascade="save-update"/>
</class>
</hibernate-mapping>

<hibernate-mapping >
<class name="myapp.Translation" table="Translations">
<composite-id class="myapp.ProductId" name="id">
<key-property name="sku" type="string">
<column length="128" name="sku"/>
</key-property>
<key-property name="manuf" type="int">
<column name="manuf"/>
</key-property>
<key-property name="catalog" type="string">
<column length="128" name="catalog"/>
</key-property>
</composite-id>
<property name="description" column="DESC"></property>
</class>
</hibernate-mapping>

Code:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

ProductId pid = new ProductId();
pid.setCatalog("catalog");
pid.setManuf(11);
pid.setSku("sku");

Translation translation = new Translation();
translation.setId(pid);
translation.setDescription("description");
      
Product testProduct = new Product();
testProduct.setId(pid);
testProduct.setTranslation(translation);
session.save(testProduct);

session.getTransaction().commit();



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