因此,我正在使用使用许多复合键的数据库。我正在尝试使用JPA /休眠来为一种关系建立一个JoinTable。这是正在做的精简示例
@Entity
@Table(name = "PROTAGONIST")
public class Protagonist {
private Integer id;
private String name;
@Id
@Column(name = "id", nullable = false)
public Integer getId() {return id;}
public void setId(Integer id) { this.id = id;}
@Column(name = "pro_name", nullable = false, length = 50)
public String getName() {return name;}
public void setName(String name) { this.name = name;}
}
@Embeddable
public class ItemId {
private int pId;
private short invSlot;
@Column(name = "P_Id", nullable = false)
public int getpId() {return pId;}
public void setpId(int pId) { this.pId = pId;}
@Column(name = "Inv_SlotNum", nullable = false)
public short getInvSlot() {return invSlot;}
public void setInvSlot(short invSlot) { this.invSlot = invSlot;}
}
public class Item {
private ItemId id;
private String itemName;
private Double cost;
private Set<Buff> buffs;
@EmbeddedId
public ItemId getId() {return id;}
public void setId(ItemId id) { this.id = id;}
@Column(name = "Item_Name", nullable = false, length = 100)
public String getItemName() {return itemName;}
public void setItemName(String name) { this.itemName = name;}
@Column(name = "Item_Cost")
public Double getCost() {return cost;}
public void setCost(Double cost) { this.cost = cost;}
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "BUFFSONITEMS",
joinColumns = {
@JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
@JoinColumn(name = "Inv_SlotNum", referencedColumnName = "Inv_SlotNum")
},
inverseJoinColumns = {
@JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
@JoinColumn(name = "Buff_SlotNum", referencedColumnName = "Buff_SlotNum")
}
)
public Set<Buff> getBuffs() {return buffs;}
public void setBuffs(Set<Buff> buffs) { this.buffs = buffs;}
}
@Embeddable
public class BuffId {
private Integer pId;
private Short buffSlotNum;
@Column(name = "P_Id", nullable = false)
public Integer getpId() {return pId;}
public void setpId(Integer pId) { this.pId = pId;}
@Column(name = "Buff_SlotNum", nullable = false)
public Short getBuffSlotNum() {return buffSlotNum;}
public void setBuffSlotNum(Short buffSeqNum) { this.buffSlotNum = buffSeqNum;}
}
@Entity
@Table(name = "BUFF")
public class Buff {
private BuffId id;
private String buffName;
private Long duration;
private Set<Item> buffedItems;
@EmbeddedId
public BuffId getId() {return id;}
public void setId(BuffId id) { this.id = id;}
@Column(name = "Buff_Name", nullable = false, length = 100)
public String getBuffName() {return buffName;}
public void setBuffName(String name) { this.buffName = name;}
@Column(name = "Duration", nullable = false)
public Long getDuration() {return duration;}
public void setDuration(Long duration) { this.duration = duration;}
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "BUFFSONITEMS",
joinColumns = {
@JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
@JoinColumn(name = "Buff_SlotNum", referencedColumnName = "Buff_SlotNum")
},
inverseJoinColumns = {
@JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
@JoinColumn(name = "Inv_SlotNum", referencedColumnName = "Inv_SlotNum")
}
)
public Set<Item> getBuffedItems() {return buffedItems;}
public void setBuffedItems(Set<Item> buffedItems) { this.buffedItems = buffedItems;}
}
每当我尝试启动Spring Boot时,都会出现以下异常 org.hibernate.MappingException:集合中映射的重复列:com.blankd.composite.key.Item.buffs列:P_Id 。 BUFFSONITEMS表使用所有3列作为该表中每一行的主键的一部分。所有三列在各自的表上也都具有伪造的键约束。这意味着P_Id在Buff和Item上都具有forgein键约束。
我不确定我在做什么错,因为我需要P_Id才能唯一标识每个表中的行。
答案 0 :(得分:1)
您必须选择多对多关系中的一侧作为“拥有”侧。然后,“反”面必须使用mappedBy
元素。
如果您选择Item.buffs
作为拥有者,则可以这样映射Buff.buffedItems
:
@ManyToMany(mappedBy="buffs")
public Set<Item> getBuffedItems() {return buffedItems;}