我有一个存储工作坊的实体,我正在使用复合主键。
我不喜欢自动生成密钥的概念,直到现在主要使用业务派生密钥,例如电子邮件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关系,在这里,场地实际上是三个城市预先指定的中心中的5个
@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?
或者我在模拟它的方式上弄错了吗?
答案 0 :(得分:0)
您有一个由嵌入式WorkshopId
表示的复合主键
嵌入Workshop
。主键的两个字段都需要连接到链接表中的目标实体 - 因此您需要2个joincolumns和一个inversejoin。您只需要添加缺少的连接;
@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专栏。