[英]Hibernate one to many mapping where one class has a composite primary key on many side
[英]mapping ManyToOne bidirectional relation where one side has a composite primary key
我有一个用于存储使用复合主键的Workshops的实体。
我不喜欢自动生成密钥的概念,并且直到现在,大多数人还是使用业务衍生密钥,例如实体的电子邮件ID等。 但是在这里,工作坊实体似乎没有主键的自然候选者,因此我选择了组合键。我创建了一个WorkshopIdType
,它是一个枚举,包含将要组织的三个可能的工作坊
public enum WorkshopIdType implements Serializable {
FOUNDATION("FND"), INTERMEIDATE("IMT"), ADVANCED("ADV");
private final String name;
private WorkshopIdType(String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
public boolean equals(String otherName) {
return (otherName == null) ? false : name.equals(otherName);
}
}
然后,我有一个Embeddable类作为主键; 在这种情况下,研讨会类型和日期的组合在我看来是最适合主键的
@Embeddable
@Access(AccessType.FIELD)
public class WorkshopId implements Serializable {
private static final long serialVersionUID = -7287847106009163526L;
private String workshopIdType;
private Date date;
@Column(name = "id", nullable = false)
public String getWorkshopIdType() {
return workshopIdType;
}
public void setWorkshopIdType(WorkshopIdType workshopIdType) {
this.workshopIdType = workshopIdType.toString();
}
@Temporal(TemporalType.DATE)
@Column(name = "date", nullable = false)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
该实体还与Venue
建立了ManyToOne关系,这里的Venues实际上是三个城市中预先指定的五个中心
@Entity
public class Workshop implements Serializable {
private static final long serialVersionUID = -5516160437873476233L;
private WorkshopId id;
private Venue venue;
private Integer seatsAvailable;
@EmbeddedId
public WorkshopId getId() {
return id;
}
public void setId(WorkshopId id) {
this.id = id;
}
@ManyToOne
@JoinTable(name = "workshop_venue", joinColumns = { @JoinColumn(name = "workshop_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "venue_name", referencedColumnName = "name") })
public Venue getVenue() {
return venue;
}
public void setVenue(Venue venue) {
this.venue = venue;
}
@Column(name = "seats_available", nullable = false)
public Integer getSeatsAvailable() {
return seatsAvailable;
}
public void setSeatsAvailable(Integer seatsAvailable) {
this.seatsAvailable = seatsAvailable;
}
}
问题是在使用复合键的情况下将此ManyToOne与JoinTable映射
@ManyToOne
@JoinTable(name = "workshop_venue", joinColumns = { @JoinColumn(name = "workshop_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "venue_name", referencedColumnName = "name") })
public Venue getVenue() {
return venue;
}
如我所料,这将无法正常工作,无法找到逻辑名称为“ id”的列。 我将通过JoinTable使用ManyToOne,因为在某些情况下,用户应该了解针对给定场地安排了培训。 在这种情况下,如何指定referencedColumnName?
还是我在建模时弄错了一切?
您有一个复合主键,由嵌入在Workshop
的可嵌入WorkshopId
表示。 主键的两个字段都需要连接到链接表中的目标实体–因此,您需要2个连接列和1个反向连接。 您只需要添加丢失的联接;
@ManyToOne
@JoinTable(name = "workshop_venue",
joinColumns =
{ @JoinColumn(name = "workshop_id", referencedColumnName = "id"),
/* Add this joincolumn */
@JoinColumn(name = "date_id", referencedColumnName = "date") },
inverseJoinColumns =
{ @JoinColumn(name = "venue_name", referencedColumnName = "name") })
public Venue getVenue() {
return venue;
当然,您需要确保链接表具有这三个字段。 我猜您缺少date_id列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.