【问题标题】:Incorrect @onetomany annotation in HibernateHibernate 中的 @onetomany 注释不正确
【发布时间】: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,你应该使用对应的注解吧?
  • 现在是午夜,我可能会错过一些东西。但是一个话题 -> 很多演讲者,怎么可能是多对多的关系呢?
  • 一个主题 -> 多位演讲者,但在您之前的评论中您说:“一位演讲者可能参与多个主题。...”

标签: java hibernate


【解决方案1】:

您正在描述一个多对多关系并且必须使用@ManyToMany 注释。像这样的:

@Entity
@Table(name="TOPICS")
public class Topic implements Serializable {

    @Id
    @GeneratedValue
    private long topicId;      

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "TOPIC_SPEAKERS",
    joinColumns = {
        @JoinColumn(name = "topicId")},
    inverseJoinColumns = {
        @JoinColumn(name = "speakerId")})
    private Set<Speaker> speakersList;




@Entity
@Table(name="SPEAKERS")
public class Speaker implements Serializable {

    @Id
    @GeneratedValue
    private long speakerId;

    @ManyToMany(mappedBy = "speakersList")
    private Set<Topic> topics;

    private String speakerName;

【讨论】:

  • 一会儿,我现在去检查一下
  • @RafaelOsipov 没问题 :)
猜你喜欢
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 2012-10-26
  • 2011-04-04
  • 1970-01-01
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多