Enterprise Java
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.
1 2 3 4 5 | CREATE TABLE REPORT ( ID INT( 10 ) NOT NULL AUTO_INCREMENT, NAME VARCHAR( 45 ) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
1 2 3 4 5 6 | 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
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | <? xml version = "1.0" ?> <! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" < 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
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | <? xml version = "1.0" ?> <! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" < 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.
These articles on the Internet as a shit in the toilet.
Example – shit, the theme has not been disclosed.
Hi.
Thanks. I am trying to run the example. Somehow unable to do so. Would you be able to provide a quick example of insert and update.
I got this working…thank you :)
This worked for me thank you for the article really useful. :)
Hi ,
Can you please provide this with annotattions?
Thanks a lot, this work for me, a hard day :)