title: Hibernate error: one-to-one mapping on superclass and subclass
body: <p>I'm working on a project with Hibernate and MySQL, use annotation for mapping database to data object model. I need to mapping one-to-one between superclass and subclass on ID primary key of their classes. I've modified the sample of this tutorial: <a href="http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example/" rel="nofollow">http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example/</a></p>
  
  <p>DDL script:</p>
  
  <pre><code>CREATE DATABASE IF NOT EXISTS mkyong;
  USE mkyong;
  
  --
  -- Definition of table `stock`
  --
  
  DROP TABLE IF EXISTS `stock`;
  CREATE TABLE `stock` (
    `STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `STOCK_CODE` varchar(10) NOT NULL,
    `STOCK_NAME` varchar(20) NOT NULL,
    PRIMARY KEY (`STOCK_ID`) USING BTREE,
    UNIQUE KEY `UNI_STOCK_NAME` (`STOCK_NAME`),
    UNIQUE KEY `UNI_STOCK_ID` (`STOCK_CODE`) USING BTREE
  ) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;
  
  --
  -- Definition of table `stock_detail`
  --
  DROP TABLE IF EXISTS `mkyong`.`stock_detail`;
  CREATE TABLE  `mkyong`.`stock_detail` (
    `STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `COMP_NAME` varchar(100) NOT NULL,
    `COMP_DESC` varchar(255) DEFAULT NULL,
    `REMARK` varchar(255) DEFAULT NULL,
    `LISTED_DATE` date NOT NULL,
    PRIMARY KEY (`STOCK_ID`) USING BTREE,
    CONSTRAINT `FK_STOCK_ID` FOREIGN KEY (`STOCK_ID`) REFERENCES `stock` (`STOCK_ID`)
  ) ENGINE=InnoDB AUTO_INCREMENT=86 DEFAULT CHARSET=utf8;
  </code></pre>
  
  <p>Here is my code after modifying:
  Stock.java (superclass)</p>
  
  <pre><code>package com.mkyong.common;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.FetchType;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.OneToOne;
  import javax.persistence.Table;
  import javax.persistence.UniqueConstraint;
  
  import org.hibernate.annotations.Cascade;
  import org.hibernate.annotations.CascadeType;
  
  @Entity
  @Table(name = "stock", catalog = "mkyong", uniqueConstraints = {
          @UniqueConstraint(columnNames = "STOCK_NAME"),
          @UniqueConstraint(columnNames = "STOCK_CODE") })
  public class Stock implements java.io.Serializable {
  
      private Integer stockId;
      private String stockCode;
      private String stockName;
      private StockDetail stockDetail;
  
      public Stock() {
      }
  
      public Stock(String stockCode, String stockName) {
          this.stockCode = stockCode;
          this.stockName = stockName;
      }
  
      public Stock(String stockCode, String stockName, StockDetail stockDetail) {
          this.stockCode = stockCode;
          this.stockName = stockName;
          this.stockDetail = stockDetail;
      }
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "STOCK_ID", unique = true, nullable = false)
      public Integer getStockId() {
          return this.stockId;
      }
  
      public void setStockId(Integer stockId) {
          this.stockId = stockId;
      }
  
      @Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
      public String getStockCode() {
          return this.stockCode;
      }
  
      public void setStockCode(String stockCode) {
          this.stockCode = stockCode;
      }
  
      @Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
      public String getStockName() {
          return this.stockName;
      }
  
      public void setStockName(String stockName) {
          this.stockName = stockName;
      }
  
      @OneToOne(fetch = FetchType.LAZY, mappedBy = "stock")
      @Cascade({CascadeType.SAVE_UPDATE})
      public StockDetail getStockDetail() {
          return this.stockDetail;
      }
  
      public void setStockDetail(StockDetail stockDetail) {
          this.stockDetail = stockDetail;
      }
  
  }
  </code></pre>
  
  <p>and StockDetail.java (subclass)</p>
  
  <pre><code>package com.mkyong.common;
  
  // Generated Jan 19, 2010 6:46:22 PM by Hibernate Tools 3.2.5.Beta
  
  import java.util.Date;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.FetchType;
  import javax.persistence.GeneratedValue;
  import javax.persistence.Id;
  import javax.persistence.OneToOne;
  import javax.persistence.PrimaryKeyJoinColumn;
  import javax.persistence.Table;
  import javax.persistence.Temporal;
  import javax.persistence.TemporalType;
  import org.hibernate.annotations.GenericGenerator;
  import org.hibernate.annotations.Parameter;
  
  /**
   * StockDetail generated by hbm2java
   */
  @Entity
  @Table(name = "stock_detail", catalog = "mkyong")
  public class StockDetail extends Stock implements java.io.Serializable {
  
      private Integer stockId;
      private Stock stock;
      private String compName;
      private String compDesc;
      private String remark;
      private Date listedDate;
  
      public StockDetail() {
      }
  
      public StockDetail(Stock stock, String compName, Date listedDate) {
          this.stock = stock;
          this.compName = compName;
          this.listedDate = listedDate;
      }
  
      public StockDetail(Stock stock, String compName, String compDesc,
              String remark, Date listedDate) {
          this.stock = stock;
          this.compName = compName;
          this.compDesc = compDesc;
          this.remark = remark;
          this.listedDate = listedDate;
      }
  
      @GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "stock"))
      @Id
      @GeneratedValue(generator = "generator")
      @Column(name = "STOCK_ID", unique = true, nullable = false)
      public Integer getStockId() {
          return this.stockId;
      }
  
      public void setStockId(Integer stockId) {
          this.stockId = stockId;
      }
  
      @OneToOne(fetch = FetchType.LAZY)
      @PrimaryKeyJoinColumn
      public Stock getStock() {
          return this.stock;
      }
  
      public void setStock(Stock stock) {
          this.stock = stock;
      }
  
      @Column(name = "COMP_NAME", nullable = false, length = 100)
      public String getCompName() {
          return this.compName;
      }
  
      public void setCompName(String compName) {
          this.compName = compName;
      }
  
      @Column(name = "COMP_DESC")
      public String getCompDesc() {
          return this.compDesc;
      }
  
      public void setCompDesc(String compDesc) {
          this.compDesc = compDesc;
      }
  
      @Column(name = "REMARK")
      public String getRemark() {
          return this.remark;
      }
  
      public void setRemark(String remark) {
          this.remark = remark;
      }
  
      @Temporal(TemporalType.DATE)
      @Column(name = "LISTED_DATE", nullable = false, length = 10)
      public Date getListedDate() {
          return this.listedDate;
      }
  
      public void setListedDate(Date listedDate) {
          this.listedDate = listedDate;
      }
  }
  </code></pre>
  
  <p>I've tried to insert some record:
  MainApplication.java</p>
  
  <pre><code>package com.mkyong.common;
  
  import java.util.Date;
  import org.hibernate.Session;
  import com.mkyong.persistence.HibernateUtil;
  
  public class App {
  
      public static void main(String[] args) {
          System.out.println("Maven + Hibernate One-to-One example + MySQL");
          Session session = HibernateUtil.getSessionFactory().openSession();
  
          session.beginTransaction();
  
          Stock stock = new Stock();
  
          stock.setStockCode("9588");
          stock.setStockName("MSFT");
  
          StockDetail stockDetail = new StockDetail();
          stockDetail.setCompName("Microsoft Company");
          stockDetail.setCompDesc("Blah blah");
          stockDetail.setListedDate(new Date());
  
          stock.setStockDetail(stockDetail);
          stockDetail.setStock(stock);
  
          session.save(stock);
  
          session.getTransaction().commit();
  
      }
  }
  </code></pre>
  
  <p>but an error occurred:
  <strong>Initial SessionFactory creation failed.org.hibernate.AnnotationException: Unable to define/override @Id(s) on a subclass: com.mkyong.common.StockDetail</strong></p>
  
  <p>Could you please help me to resolve this issue? Thank you so much.</p>