Java 为什么@OneToMany属性会出现主键冲突?
我有一个实体:Java 为什么@OneToMany属性会出现主键冲突?,java,hibernate,jpa,h2,spring-data-jpa,Java,Hibernate,Jpa,H2,Spring Data Jpa,我有一个实体: @Entity public class Student { @GeneratedValue(strategy = GenerationType.AUTO) @Id private long id; @OneToMany private Set<Course> courses; } 我正在使用Spring数据JPA和Hibernate以及H2作为数据库 应用程序创建了自己的数据库表: HibernateJpaVendorA
@Entity
public class Student {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private long id;
@OneToMany
private Set<Course> courses;
}
我正在使用Spring数据JPA和Hibernate以及H2作为数据库
应用程序创建了自己的数据库表:
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.H2);
那么,为什么会有一个独特的约束呢
更新:
我看到Hibernate添加了约束:
Hibernate: alter table student_courses add constraint UK_a8c48f36df374f1293c46699c83 unique (courses)
我如何告诉Hibernate不要创建它
谢谢 您必须使用
GenerationType.TABLE
而不是GenerationType.AUTO
。这样,jpa使用序列表分配id,您可能永远不需要生成序列或自动递增值或降低可移植性的触发器。序列/jpa/hibern没有问题。根据您的日志,错误发生在学生课程上insert into student_courses
UK_1DBE7B943AC44E1B841DA2688EB_INDEX_5
似乎,您在学生课程表中对课程设置了unquie约束。删除该取消静态约束/您可能需要为取消静态约束添加学生和课程的组合,而不仅仅是课程。由于冲突发生在
学生课程表中,因此您似乎试图两次保持相同的关系。您映射了一个集合
,该集合向Hibernate发出信号,表示这些关系必须发生不超过一次。检查生成的DDL中课程ID、学生ID的唯一索引
原因可能是您的程序逻辑中存在缺陷(例如,将课程
上与等于
相关的字段添加到集合后修改这些字段,或者课程
实体中存在错误的等于
)
如果学生
可以参加课程
不止一次(例如第一次失败),你必须自己做出决定(现实世界中的客户,因为这是一个商业决定)
可能是您设置了@OneToMany
,而实际上您有一个@ManyToMany
关系
假设课程
没有自动生成的Id,那么当第二个学生添加同名课程时就会出现问题。
由于这是一对多关系,将使用相同的唯一受限Id创建一个新课程,但该Id不起作用。我将学生Id和课程Id更改为GenerationType.TABLE,而不是AUTO。我仍然收到相同的错误。这是尝试插入两个具有相同课程的学生。学生是唯一的。课程是同样。为什么Hibernate会在那里创建一个唯一的索引?请显示你的课程
实体。看起来你的映射是错误的。可能是@manytomy
或者你缺少了一个映射,如果映射在两侧。是的,你是对的,我应该使用@manytomy
。我只是在想当我编写实体时,关于一个学生学习多门课程,但由于多个学生可以学习同一门课程,因此实际上是@manytomy
,修复了它,谢谢!约束和表都是由应用程序本身生成的{{hibernateJpaVendorAdapter.setGenerateDdl(true)},那么问题就变成了为什么Hibernate会创建那个约束?因为你的课程已经设置好了,所以它假设有unquie。你可以使用@CollectionTable注释来避免这个。检查
insert into student_courses
UK_1DBE7B943AC44E1B841DA2688EB_INDEX_5