最近,我们面临着带有复合id字段的休眠关联映射的棘手情况。
我们需要与一对一和多对一建立双向关联。我们的拖曳表是“ REPORT”和“ REPORT_SUMMARY”,它们之间具有从REPORT到REPORT_SUMMARY的一对多关系,而从REPORT_SUMMARY到REPORT表。
REPORT_SUMMARY表的主键定义为复合主键,它由自动增量id字段和REPORT表的主键组成。
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;
休眠实体类是休假的。
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;
}
}
报表对象具有ReportSummary对象的集合,ReportSummaryId具有对Report对象的引用。 此实现的最重要部分是休眠映射文件。 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>
参考: 如何在我们的JCG合作伙伴 Semika loku kaluge的Code Box博客上将Hibernate用于复合ID以及关联映射 。
翻译自: https://www.javacodegeeks.com/2012/08/hibernate-composite-ids-with.html