H2 create-drop 模式中的唯一索引或主键冲突
Unique index or primary key violation in H2 create-drop mode
我在 H2 数据库中有 3 个表 course
、paper
和 course_paper
,在 application.properties 中配置了 create-drop
选项。每当我尝试按 data.sql
向表中插入数据时,我都会遇到唯一索引或主键冲突。下面是我的实体 class 和关系注释 & data.sql
。请提供一些解决方案或指导我解决此问题。
1 : 基础实体
@MappedSuperclass
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
2:课程实体
@Entity
@Table(
name = "course",
uniqueConstraints = {
@UniqueConstraint(columnNames = "id")
}
)
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public class CourseEntity extends BaseEntity {
@Column(name = "stream")
private String stream;
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "course_paper", joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "paper_id", referencedColumnName = "id")})
private Set<PaperEntity> paperEntities;
public CourseEntity(Course course) {
this.setId(course.getId());
this.setName(course.getName());
this.setStream(course.getStream());
}
}
3:纸实体
@Entity
@Table(name = "paper",
uniqueConstraints = {
@UniqueConstraint(columnNames = "id")
})
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class PaperEntity extends BaseEntity {
@Column(name = "name")
private String name;
@Column(name = "symbolic_name")
private String symbolicName;
public PaperEntity(Paper paper){
this.setId(paper.getId());
this.setName(paper.getName());
this.setSymbolicName(paper.getSymbolicName());
}
}
4 : data.sql
INSERT INTO `course` VALUES (1,'ARTS','+2 1St Year'),(2,'ARTS','+2 2nd Year'),(3,'ARTS','+3 1St Year'),(4,'ARTS','+3 2nd Year'),(5,'ARTS','+3 3rd Year'),(6,'SCIENCE','+2 1St Year'),(7,'SCIENCE','+2 2nd Year'),(8,'SCIENCE','+3 1St Year'),(9,'SCIENCE','+3 2nd Year'),(10,'SCIENCE','+3 3rd Year');
INSERT INTO `paper` VALUES (1,'Pol.Science','Political Science'),(2,'Eco','Economics'),(3,'Math','Mathematics'),(4,'Phy','Physics'),(5,'Chem','Chemestry');
INSERT INTO `course_paper` VALUES(1,1),(1,2),(2,1),(2,2);
5:错误:
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_HU9K94I7MTNKS4X0Y0207JBGG_INDEX_2 ON PUBLIC.COURSE_PAPER(PAPER_ID) VALUES 1"; SQL statement:
INSERT INTO `course_paper` VALUES(1,1),(1,2),(2,1),(2,2)
您有 @OneToMany
从 CourseEntity
到 PaperEntity
的关系。
这意味着每篇论文最多只能被一门课程引用。
但是在错误消息中您可以看到相同的 PAPER_ID
与两个课程组合在一起。
然后,这会根据您的 JPA 实现根据您的实体注释生成的约束触发错误。
要解决此问题,请从插入语句中删除元组,以便每篇论文最多被引用一次,或者将一对多关系更改为多对多关系。
我在 H2 数据库中有 3 个表 course
、paper
和 course_paper
,在 application.properties 中配置了 create-drop
选项。每当我尝试按 data.sql
向表中插入数据时,我都会遇到唯一索引或主键冲突。下面是我的实体 class 和关系注释 & data.sql
。请提供一些解决方案或指导我解决此问题。
1 : 基础实体
@MappedSuperclass
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
2:课程实体
@Entity
@Table(
name = "course",
uniqueConstraints = {
@UniqueConstraint(columnNames = "id")
}
)
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public class CourseEntity extends BaseEntity {
@Column(name = "stream")
private String stream;
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "course_paper", joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "paper_id", referencedColumnName = "id")})
private Set<PaperEntity> paperEntities;
public CourseEntity(Course course) {
this.setId(course.getId());
this.setName(course.getName());
this.setStream(course.getStream());
}
}
3:纸实体
@Entity
@Table(name = "paper",
uniqueConstraints = {
@UniqueConstraint(columnNames = "id")
})
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class PaperEntity extends BaseEntity {
@Column(name = "name")
private String name;
@Column(name = "symbolic_name")
private String symbolicName;
public PaperEntity(Paper paper){
this.setId(paper.getId());
this.setName(paper.getName());
this.setSymbolicName(paper.getSymbolicName());
}
}
4 : data.sql
INSERT INTO `course` VALUES (1,'ARTS','+2 1St Year'),(2,'ARTS','+2 2nd Year'),(3,'ARTS','+3 1St Year'),(4,'ARTS','+3 2nd Year'),(5,'ARTS','+3 3rd Year'),(6,'SCIENCE','+2 1St Year'),(7,'SCIENCE','+2 2nd Year'),(8,'SCIENCE','+3 1St Year'),(9,'SCIENCE','+3 2nd Year'),(10,'SCIENCE','+3 3rd Year');
INSERT INTO `paper` VALUES (1,'Pol.Science','Political Science'),(2,'Eco','Economics'),(3,'Math','Mathematics'),(4,'Phy','Physics'),(5,'Chem','Chemestry');
INSERT INTO `course_paper` VALUES(1,1),(1,2),(2,1),(2,2);
5:错误:
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_HU9K94I7MTNKS4X0Y0207JBGG_INDEX_2 ON PUBLIC.COURSE_PAPER(PAPER_ID) VALUES 1"; SQL statement:
INSERT INTO `course_paper` VALUES(1,1),(1,2),(2,1),(2,2)
您有 @OneToMany
从 CourseEntity
到 PaperEntity
的关系。
这意味着每篇论文最多只能被一门课程引用。
但是在错误消息中您可以看到相同的 PAPER_ID
与两个课程组合在一起。
然后,这会根据您的 JPA 实现根据您的实体注释生成的约束触发错误。
要解决此问题,请从插入语句中删除元组,以便每篇论文最多被引用一次,或者将一对多关系更改为多对多关系。