【发布时间】:2013-03-14 19:49:10
【问题描述】:
我正在研究 Hibernate,遇到了一个与 Hibernate 注释相关的不清楚的情况。
假设我们有两个实体:
主题和演讲者
一个主题可能与许多演讲者相关。一个主题可能有多个演讲者。 一位演讲者可以参与多个主题。
如下图:
我的普通应用程序包含两个实体类:主题类和扬声器类
Topic 类包含注释,通过 TOPIC_SPEAKERS 表声明与 SPEAKERS 的一对多关系。如果 TOPIC_SPEAKERS 表不存在,则在运行时生成。
Topic.class(跳过不相关的代码)
@Entity
@Table(name="TOPICS")
public class Topic implements Serializable {
@Id
@GeneratedValue
private long topicId;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "TOPIC_SPEAKERS",
joinColumns = {
@JoinColumn(name = "topicId")},
inverseJoinColumns = {
@JoinColumn(name = "speakerId")})
private List<Speaker> speakersList;
还有 Speaker 类头:
@Entity
@Table(name="SPEAKERS")
public class Speaker implements Serializable {
@Id
@GeneratedValue
private long speakerId;
private String speakerName;
我在 SPEAKERS 表中添加了两条记录,看起来像这样:
然后我参考第一个演讲者(John Doe)在 TOPICS 表中添加了一个主题。
TOPICS table:
and TOPIC_SPEAKERS table:
一切正常,直到我尝试添加另一个主题,即第一个演讲者(John Doe)。即在 TOPICS 表中添加“第二个主题”,并将“TOPIC_SPEAKERS”中“第二个主题”的引用添加到第一个发言者(John Doe)。
生成的 TOPIC_SPEAKERS 应该是这样的(65536 - John Doe 的 id):
# TOPICID SPEAKERID
1 131072 65536
2 132111 65536
但 Hibernate 不允许向 TOPIC_SPEAKERS 插入具有重复 SPEAKERID 值的记录。
我收到以下错误:
could not insert collection: [simpledbtest.model.Topic.speakersList#163840]
SEVERE: The statement was aborted because it would have caused a duplicate key value
in a unique or primary key constraint or unique index identified by 'SQL130314230217010'
defined on 'TOPIC_SPEAKERS'.
....
Caused by: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because
it would have caused a duplicate key value in a unique or primary key constraint or unique
index identified by 'SQL130314230217010' defined on 'TOPIC_SPEAKERS'.
....
Caused by: org.apache.derby.client.am.SqlException: The statement was aborted because it
would have caused a duplicate key value in a unique or primary key constraint or unique index
identified by 'SQL130314230217010' defined on 'TOPIC_SPEAKERS'.
我的问题 - 如何更改 Topic 类中的注释以允许生成的 TOPIC_SPEAKERS 表中的列值重复?
谢谢。
【问题讨论】:
-
为什么需要一对多关系中的 topic_speakers 表?通常在一对一的情况下,您只需在演讲者表中创建一个外键 topic_id。只需使用 @ManyToOne @JoinColumn(name="topic_id") 注释 List
-
一位演讲者可以参与多个主题。在这种情况下,带有扬声器记录的外键将不适合。
-
表示关系是@ManyToMany,你应该使用对应的注解吧?
-
现在是午夜,我可能会错过一些东西。但是一个话题 -> 很多演讲者,怎么可能是多对多的关系呢?
-
一个主题 -> 多位演讲者,但在您之前的评论中您说:“一位演讲者可能参与多个主题。...”