在 JPA/Hibernate 中使用复合键连接表
好的,我们的数据库团队提出了以下结构。我无法更改它:
报告
- 具有参考号 (REF_NR) 作为其 PID
- 以及有关报告、报告日期等的一些数据
属性
- 具有参考号 (REF_NR)和 建筑物编号 (BLG_NR) 作为其复合 PID。报告的 REF_NR 将与报告中所有属性的 REF_NR 相匹配,并通过其 BLG_NR 进一步索引。
- 加上有关建筑、平方英尺等的一些数据
建筑数据
- 具有参考编号 (REF_NR)、建筑编号 (BLG_NR)、结构类型代码 (STRCT_TYP_CD) 和材料类型代码 (MTRL_TYP_CD)
- 具有值它通常表示给定结构类型(即给定材料类型)的 %ge。例如,50% 的屋顶是石板,50% 的屋顶是瓷砖,依此类推,
我试图将这些连接在一起以引入报告、所有相关建筑物以及每栋建筑物的所有施工数据,但我很漂亮对于 JPA 和 JPA 来说是个菜鸟。休眠注释。
因此,请帮助我确定将这些东西连接在一起的正确的类和注释。或者甚至只是一个非常好的示例的良好链接也会有所帮助。
@Entity
@Table(name="RCT_REPORT")
public class Report implements Serializable {
private Set<Building> buildings;
private long referenceNumber;
@Id
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@OneToMany(mappedBy="report", fetch=FetchType.EAGER)
public Set<Building> getBuildings() {
return this.buildings;
}
public void setBuildings(Set<Building> buildings) {
this.buildings = buildings;
}
}
@Entity
@Table(name="RCT_BUILDING")
public class Building implements Serializable {
private Report report;
private Set<ConstructionData> constructionData;
private BuildingPK id;
@EmbeddedId
public BuildingPK getId() {
return this.id;
}
public void setId(BuildingPK id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name="REF_NR", insertable=false, updatable=false)
public Report getReport() {
return this.report;
}
public void setReport(Report report) {
this.report = report;
}
@OneToMany(mappedBy="building", fetch=FetchType.EAGER)
@JoinColumns ({
@JoinColumn(name="REF_NR", referencedColumnName = "REF_NR"),
@JoinColumn(name="BLG_NR", referencedColumnName = "BLG_NR")
})
public Set<ConstructionData> getConstructionData() {
return this.constructionData;
}
public void setConstructionData(Set<ConstructionData> constructionData) {
this.constructionData = constructionData;
}
}
@Embeddable
public class BuildingPK implements Serializable {
private long referenceNumber;
private int buildingNumber;
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@Column(name="BLG_NR")
public int getBuildingNumber() {
return this.buildingNumber;
}
public void setBuildingNumber(int buildingNumber) {
this.buildingNumber = buildingNumber;
}
public boolean equals(Object other) {
...
}
public int hashCode() {
...
}
}
@Entity
@Table(name="CNSTRCTN_DATA")
public class ConstructionData implements Serializable {
private ConstructionDataPK id;
private BigDecimal value;
private Building building;
@EmbeddedId
public ConstructionDataPK getId() {
return this.id;
}
public void setId(ConstructionDataPK id) {
this.id = id;
}
@Column(name="MTRL_SEL_VAL")
public BigDecimal getValue() {
return this.value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
@ManyToOne
@JoinColumns ({
@JoinColumn(name="REF_NR", referencedColumnName="REF_NR", insertable=false, updatable=false),
@JoinColumn(name="BLG_NR", referencedColumnName="BLG_NR", insertable=false, updatable=false)
})
public Building getBuilding() {
return this.building;
}
public void setBuilding(Building building) {
this.Building = building;
}
}
@Embeddable
public class ConstructionDataPK implements Serializable {
private long referenceNumber;
private int buildingNumber;
private String structureTypeCode;
private String materialTypeCode;
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@Column(name="BLG_NR")
public int getbuildingNumber() {
return this.buildingNumber;
}
public void setbuildingNumber(int buildingNumber) {
this.buildingNumber = buildingNumber;
}
@Column(name="STRCT_TYP_CD")
public String getStructureTypeCode() {
return this.structureTypeCode;
}
public void setStructureTypeCode(String structureTypeCode) {
this.structureTypeCode = structureTypeCode;
}
@Column(name="MTRL_TYP_CD")
public String getMaterialTypeCode() {
return this.materialTypeCode;
}
public void setMaterialTypeCode(String materialTypeCode) {
this.materialTypeCode = materialTypeCode;
}
public boolean equals(Object other) {
...
}
public int hashCode() {
...
}
}
正如我所说,我对此还很陌生,这一切对我来说看起来都是正确的,但我确信我错过了一些东西。
谢谢! 彼得
Okay, our DB team has come up with the following structure. I cannot change it:
Report
- has Reference Number (REF_NR) as its PID
- plus some data about the report, report date and so on
Property
- has Reference Number (REF_NR) and Building Number (BLG_NR) as its compound PID. The REF_NR of the Report will match the REF_NR of all the Properties on the report, who are further indexed by their BLG_NR.
- plus some data about the build, square footage and so on
Construction Data
- has Reference Number (REF_NR), Building Number (BLG_NR), Structure Type Code (STRCT_TYP_CD) and Material Type Code (MTRL_TYP_CD)
- has a value which generally expresses the %ge of the given structure type that is the given material type. For example, 50% of the ROOF is SLATE and 50% of the ROOF is TILE, and so on
I am trying to join these together to bring in the Report, all associated buildings and all construction data for each building, but I am pretty much a noob to JPA & hibernate annotations.
So, please help me determine the proper classes and annotations for joining these things together. Or even just a good link to a really good example would help.
@Entity
@Table(name="RCT_REPORT")
public class Report implements Serializable {
private Set<Building> buildings;
private long referenceNumber;
@Id
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@OneToMany(mappedBy="report", fetch=FetchType.EAGER)
public Set<Building> getBuildings() {
return this.buildings;
}
public void setBuildings(Set<Building> buildings) {
this.buildings = buildings;
}
}
@Entity
@Table(name="RCT_BUILDING")
public class Building implements Serializable {
private Report report;
private Set<ConstructionData> constructionData;
private BuildingPK id;
@EmbeddedId
public BuildingPK getId() {
return this.id;
}
public void setId(BuildingPK id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name="REF_NR", insertable=false, updatable=false)
public Report getReport() {
return this.report;
}
public void setReport(Report report) {
this.report = report;
}
@OneToMany(mappedBy="building", fetch=FetchType.EAGER)
@JoinColumns ({
@JoinColumn(name="REF_NR", referencedColumnName = "REF_NR"),
@JoinColumn(name="BLG_NR", referencedColumnName = "BLG_NR")
})
public Set<ConstructionData> getConstructionData() {
return this.constructionData;
}
public void setConstructionData(Set<ConstructionData> constructionData) {
this.constructionData = constructionData;
}
}
@Embeddable
public class BuildingPK implements Serializable {
private long referenceNumber;
private int buildingNumber;
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@Column(name="BLG_NR")
public int getBuildingNumber() {
return this.buildingNumber;
}
public void setBuildingNumber(int buildingNumber) {
this.buildingNumber = buildingNumber;
}
public boolean equals(Object other) {
...
}
public int hashCode() {
...
}
}
@Entity
@Table(name="CNSTRCTN_DATA")
public class ConstructionData implements Serializable {
private ConstructionDataPK id;
private BigDecimal value;
private Building building;
@EmbeddedId
public ConstructionDataPK getId() {
return this.id;
}
public void setId(ConstructionDataPK id) {
this.id = id;
}
@Column(name="MTRL_SEL_VAL")
public BigDecimal getValue() {
return this.value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
@ManyToOne
@JoinColumns ({
@JoinColumn(name="REF_NR", referencedColumnName="REF_NR", insertable=false, updatable=false),
@JoinColumn(name="BLG_NR", referencedColumnName="BLG_NR", insertable=false, updatable=false)
})
public Building getBuilding() {
return this.building;
}
public void setBuilding(Building building) {
this.Building = building;
}
}
@Embeddable
public class ConstructionDataPK implements Serializable {
private long referenceNumber;
private int buildingNumber;
private String structureTypeCode;
private String materialTypeCode;
@Column(name="REF_NR")
public long getReferenceNumber() {
return this.referenceNumber;
}
public void setReferenceNumber(long referenceNumber) {
this.referenceNumber = referenceNumber;
}
@Column(name="BLG_NR")
public int getbuildingNumber() {
return this.buildingNumber;
}
public void setbuildingNumber(int buildingNumber) {
this.buildingNumber = buildingNumber;
}
@Column(name="STRCT_TYP_CD")
public String getStructureTypeCode() {
return this.structureTypeCode;
}
public void setStructureTypeCode(String structureTypeCode) {
this.structureTypeCode = structureTypeCode;
}
@Column(name="MTRL_TYP_CD")
public String getMaterialTypeCode() {
return this.materialTypeCode;
}
public void setMaterialTypeCode(String materialTypeCode) {
this.materialTypeCode = materialTypeCode;
}
public boolean equals(Object other) {
...
}
public int hashCode() {
...
}
}
As I said, I'm pretty new to this, and this all looks right to me, but I'm sure I'm missing something.
Thanks!
Peter
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来连接列属于关系中的“子”,而不是父。我在两个地方都有它们。
另外,虽然它没有显示,但我遇到了另一个问题,如果您只尝试映射复合键的一部分,hibernate 3.3.2 不喜欢它。在我真正的问题中,父级的 PK 中有第三个字段,该字段也在子级和子级中。我没有在连接表中映射它。添加后,一切都很好。
彼得
It looks like the join columns belong on the 'child' in the relationship, not the parent. I had them in both places.
Also, although it doesn't show it, I had another problem where hibernate 3.3.2 doesn't like it if you only try to map part of a compound key. In my real problem, there was a third field in the PK of the parent that was also in the child & I didn't have that mapped in the join table. Once I added it, everything joined up just fine.
Peter