我首先要说的是,我意识到数据库结构很糟糕,但我现在无法改变它。
话虽这么说,我需要在Hibernate(4.2.1)中创建一对多的双向关系,它不涉及主键(只有关系的“父”侧的唯一键) )并没有连接表。表示此关系的外键是从“子”到“父”的后向指针(见下文)。我搜索并尝试了各种不同的注释配置而没有运气。是我要求的可能吗?
GLOBAL_PART
CREATE TABLE "GLOBAL_PART" (
"GLOBAL_PART_ID" NUMBER NOT NULL,
"RELEASES" NUMBER,
CONSTRAINT "GLOBAL_PART_PK" PRIMARY KEY ("GLOBAL_PART_ID"),
CONSTRAINT "GLOBAL_PART_RELEASES_UK" UNIQUE ("RELEASES")
);
PART_RELEASE
CREATE TABLE "PART_RELEASE" (
"PART_RELEASE_ID" NUMBER NOT NULL,
"COLLECTION_ID" NUMBER,
CONSTRAINT "PART_RELEASE_PK" PRIMARY KEY ("PART_RELEASE_ID"),
CONSTRAINT "GLOBAL_PART_RELEASE_FK" FOREIGN KEY ("COLLECTION_ID")
REFERENCES "GLOBAL_PART" ("RELEASES") ON DELETE CASCADE ENABLE
);
参考:
PART_RELEASE GLOBAL_PART
------------------- ------------
PART_RELEASE_ID (PK) GLOBAL_PART_ID (PK)
COLLECTION_ID -------------> RELEASES (UK)
GlobalPart.java
@Entity
@Table(name = "GLOBAL_PART")
@SequenceGenerator(name = "SEQUENCE_GENERATOR", sequenceName = "GLOBAL_PART_SEQ")
public class GlobalPart extends ModelBase implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "GLOBAL_PART_ID", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GENERATOR")
private Long globalPartId;
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "COLLECTIONGID")
private Set<PartRelease> releases;
public Long getGlobalPartId() {
return globalPartId;
}
public void setGlobalPartId(Long globalPartId) {
this.globalPartId = globalPartId;
}
public Set<PartRelease> getReleases() {
return releases;
}
public void setReleases(Set<PartRelease> releases) {
this.releases = releases;
}
}
PartRelease.java
@Entity
@Table(name = "PART_RELEASE")
@SequenceGenerator(name = "SEQUENCE_GENERATOR", sequenceName = "PART_RELEASE_SEQ")
public class PartRelease extends ModelBase implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "PART_RELEASE_ID", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GENERATOR")
private String partReleaseId;
@ManyToOne
@JoinColumn(name = "RELEASES")
private GlobalPart globalPart;
public String getPartReleaseId() {
return partReleaseId;
}
public void setPartReleaseId(String partReleaseId) {
this.partReleaseId = partReleaseId;
}
public GlobalPart getGlobalPart() {
return globalPart;
}
public void setGlobalPart(GlobalPart globalPart) {
this.globalPart = globalPart;
}
}
非常感谢任何帮助!!
答案 0 :(得分:30)
首先,在双向关联中,始终存在一个定义映射的所有者方,以及一个由mappedBy
属性的存在标记的反面。
在OneToMany协会中,所有者方总是多方(在你的情况下是PartRelease)。
此外,默认情况下,连接列引用它引用的实体的ID。由于它不是您想要的,您必须指定引用的列名。
当然,必须映射RELEASES列:
public class GlobalPart extends ModelBase implements Serializable {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "globalPart")
private Set<PartRelease> partReleases;
@Column(name = "RELEASES")
private Long releasesNumber;
}
public class PartRelease extends ModelBase implements Serializable {
@ManyToOne
@JoinColumn(name = "COLLECTION_ID", referencedColumnName = "RELEASES")
private GlobalPart globalPart;
}
the documentation中详细描述了关联。你应该阅读它。
答案 1 :(得分:2)
正如this article中所述,每当您需要使用父级的非主键列映射@ManyToOne
时,您必须使用referencedColumnName
属性{ {1}}注释。
@JoinColumn
我将@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(
name = "RELEASES",
referencedColumnName = "COLLECTIONGID"
)
用于FetchType.LAZY
,因为默认使用的是EAGER提取,very bad for performance。