Hibernate Composite Ids with association mappings

Recently, We faced a tricky situation with hibernate association mapping with a composite id field. We needed to have bidirectional association with one-to-may and many-to-one.Our tow tables was “REPORT” and “REPORT_SUMMARY” which has one-to-many relationship from REPORT to REPORT_SUMMARY and many-to-one relationship from REPORT_SUMMARY to REPORT table. The primary key of REPORT_SUMMARY table is defined as a composite primary key which consists of auto increment id field and the primary key of REPORT table.
CREATE TABLE REPORT (
     ID INT(10) NOT NULL AUTO_INCREMENT,
     NAME VARCHAR(45) NOT NULL,
     PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE REPORT_SUMMARY (
   ID INT(10) NOT NULL AUTO_INCREMENT,
   NAME VARCHAR(45) NOT NULL,
   RPT_ID INT(10) NOT NULL,
   PRIMARY KEY (`ID`,`RPT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The hibernate entity classes are as fallows.
Report.java

package com.semika.autoac.entities;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Report implements Serializable{

    private static final long serialVersionUID = 9146156921169669644L;

    private Integer id;
    private String name;
    private Set<ReportSummary> reportSummaryList  = new HashSet<ReportSummary>();
    
    public Integer getId() {
         return id;
    }
    public void setId(Integer id) {
         this.id = id;
    }
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }
    public Set<ReportSummary> getReportSummaryList() {
         return reportSummaryList;
    }
    public void setReportSummaryList(Set<ReportSummary> reportSummaryList) {
         this.reportSummaryList = reportSummaryList;
    }
}

ReportSummary.java

package com.semika.autoac.entities;

import java.io.Serializable;
public class ReportSummary implements Serializable {

private static final long serialVersionUID = 8052962961003467437L;

private ReportSummaryId id;
private String name;

public ReportSummaryId getId() {
    return id;
}
public void setId(ReportSummaryId id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    ReportSummary other = (ReportSummary) obj;
    if (id == null) {
       if (other.id != null)
          return false;
       } else if (!id.equals(other.id))
          return false;
    if (name == null) {
       if (other.name != null)
          return false;
       } else if (!name.equals(other.name))
          return false;

   return true;
  }
}

ReportSummaryId.java

package com.semika.autoac.entities;

import java.io.Serializable;

public class ReportSummaryId implements Serializable{

private static final long serialVersionUID = 6911616314813390449L;

private Integer id;
private Report report;

public Integer getId() {
   return id;
}
public void setId(Integer id) {
   this.id = id;
}
public Report getReport() {
   return report;
}
public void setReport(Report report) {
   this.report = report;
}
@Override
public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((id == null) ? 0 : id.hashCode());
   result = prime * result + ((report == null) ? 0 : report.hashCode());
   return result;
}
@Override
public boolean equals(Object obj) {
   if (this == obj)
      return true;
   if (obj == null)
      return false;
   if (getClass() != obj.getClass())
      return false;
   ReportSummaryId other = (ReportSummaryId) obj;
   if (id == null) {
      if (other.id != null)
         return false;
      } else if (!id.equals(other.id))
         return false;
   if (report == null) {
      if (other.report != null)
         return false;
      } else if (!report.equals(other.report))
         return false;

   return true;
  }
}

Report object has a collection of ReportSummary objects and ReportSummaryId has a reference to Report object. The most important part of this implementation is hibernate mapping files. Report.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.semika.autoac.entities.Report" table="REPORT" >
         <id name="id" type="int" column="id" >
                 <generator class="native"/>
         </id>
         <property name="name">
               <column name="NAME" />
         </property>
         <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true">
             <key column="RPT_ID" not-null="true"></key>
             <one-to-many class="com.semika.autoac.entities.ReportSummary"/>
         </set>
     </class>
</hibernate-mapping>

ReportSummary.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.semika.autoac.entities.ReportSummary" table="REPORT_SUMMARY" >
        <composite-id name="id" class="com.semika.autoac.entities.ReportSummaryId">
             <key-property name="id" column="ID"></key-property>
             <key-many-to-one name="report" 
                              class="com.semika.autoac.entities.Report"
                              column="RPT_ID"</key-many-to-one>
        </composite-id>
        <property name="name">
             <column name="NAME" />
        </property>
    </class>
</hibernate-mapping>

Reference: How to Use Hibernate for Composite Ids with association mappings from our JCG partner Semika loku kaluge at the Code Box blog.

Share and enjoy!
Post to Facebook Post to TwitterPost to Google+Post to Delicious Post to StumbleUponAdd to LinkedInAdd to DiggAdd to RedditSend via Mail
  • фывафыва

    These articles on the Internet as a shit in the toilet.

    Example – shit, the theme has not been disclosed.



© 2010-2012 Java Code Geeks. Licenced under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.