完整性约束违规:外键 HSQL 上的唯一约束或索引违规
integrity constraint violation: unique constraint or index violation on Foreign key HSQL
我正在使用 Hibernate/Spring Boot 测试 HSQL 数据库的底层模型,我 运行 遇到了一个我找不到解决方案的问题。
这是我的简单测试,我正在尝试创建一个鞋盒实体并将其保存到数据库,并将用户对象设置为所有者的外键:
@TestConfiguration
static class ShoeboxServiceTestContextConfiguration {
@Bean
public ShoeboxService shoeboxService() {
return new ShoeboxService();
}
@Bean
public UserService userService() {
return new UserService();
}
}
@Autowired
UserService users;
@Autowired
ShoeboxService shoeboxes;
@Test
public void testSave()
{
System.out.println("save");
int userId = 1;
User user = new User(userId, "Foo", "hello@world.com");
user = users.save(user);
Shoebox sb = new Shoebox(user, "Name", "Context", "Comment", false);
UUID sbId = shoeboxes.save(sb).getId();
sb = shoeboxes.findOne(sbId);
assertNotNull(sb);
assertEquals(sb.getName(), "Name");
assertEquals(sb.getContext(), "Context");
assertEquals(sb.getComment(), "Comment");
assertEquals(sb.isShare(), false);
shoeboxes.deleteById(sbId);
users.deleteById(userId);
}
然而当它得到它时抛出一个
integrity constraint violation: unique constraint or index violation; SYS_PK_10126 table: USER
尝试将鞋盒保存到数据库时出现异常。它成功地保留了用户,并且在没有所有者 FK 附加到它时成功地保留了 Shoebox 对象,但在提供 FK 时崩溃。
这是我的用户 POJO:
@Entity
@Table(name="User")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User implements Serializable
{
@Id
@Column(name = "ID")
private long ID;
@Column(name = "Name")
private String name;
@Column(name = "Email")
private String email;
@OneToOne(fetch = FetchType.LAZY)
private Shoebox currentlySelectedBox;
@OneToMany(fetch = FetchType.LAZY)
@JsonManagedReference(value="shoebox_owner")
private List<Shoebox> shoeboxes;
// Contructors, Getters/Setters etc.
}
还有我的鞋盒 POJO:
@Entity
@Table(name="Shoebox")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Shoebox implements Serializable
{
@Id
@Column(name="ID")
UUID ID;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="OwnerID")
@JsonBackReference(value="shoebox_owner")
User owner;
@Column(name="Name")
String name;
@Column(name="Context")
String context;
@Column(name="Comment")
String comment;
@Column(name="Shared")
boolean share;
@Column(name="CreationDate")
LocalDateTime creationDate;
// Contructors, Getters/Setters etc.
}
这是数据库的 HSQL 创建脚本:
CREATE MEMORY TABLE PUBLIC.SHOEBOX(ID BINARY(255) NOT NULL PRIMARY KEY,COMMENT VARCHAR(255),CONTEXT VARCHAR(255),CREATIONDATE TIMESTAMP,NAME VARCHAR(255),SHARED BOOLEAN,OWNERID BIGINT)
CREATE MEMORY TABLE PUBLIC.USER(ID BIGINT NOT NULL PRIMARY KEY,EMAIL VARCHAR(255),NAME VARCHAR(255),CURRENTLYSELECTEDBOX_ID BINARY(255),CONSTRAINT FK3T924ODM2BIK5543K0E3UEGP FOREIGN KEY(CURRENTLYSELECTEDBOX_ID) REFERENCES PUBLIC.SHOEBOX(ID))
CREATE MEMORY TABLE PUBLIC.USER_SHOEBOX(USER_ID BIGINT NOT NULL,SHOEBOXES_ID BINARY(255) NOT NULL,CONSTRAINT FK5W8WMFC5E9RMEK7VC4N76MQVQ FOREIGN KEY(SHOEBOXES_ID) REFERENCES PUBLIC.SHOEBOX(ID),CONSTRAINT FKIR9SOKRCOQ33LCQTNR0LDXO93 FOREIGN KEY(USER_ID) REFERENCES PUBLIC.SHOEBOXUSER(ID),CONSTRAINT UK_508XA86IDIHP04FQD3D6GF8D7 UNIQUE(SHOEBOXES_ID))
ALTER TABLE PUBLIC.SHOEBOX ADD CONSTRAINT FK3J9RQBYW5VQ0IRF3FWYPG7LAB FOREIGN KEY(OWNERID) REFERENCES PUBLIC.USER(ID)
为什么会触发异常?我的注释和对象之间的 PK/FK 关系有问题吗?
非常感谢。
问题是
@ManyToOne(cascade = CascadeType.ALL)
使用CascadeType.ALL
,任何操作都将扩展到其他实体。所以在这种情况下,保存方法级联在鞋盒的用户试图再次保存它。由于您使用的是 1
的静态 ID,因此会导致键约束。
我正在使用 Hibernate/Spring Boot 测试 HSQL 数据库的底层模型,我 运行 遇到了一个我找不到解决方案的问题。
这是我的简单测试,我正在尝试创建一个鞋盒实体并将其保存到数据库,并将用户对象设置为所有者的外键:
@TestConfiguration
static class ShoeboxServiceTestContextConfiguration {
@Bean
public ShoeboxService shoeboxService() {
return new ShoeboxService();
}
@Bean
public UserService userService() {
return new UserService();
}
}
@Autowired
UserService users;
@Autowired
ShoeboxService shoeboxes;
@Test
public void testSave()
{
System.out.println("save");
int userId = 1;
User user = new User(userId, "Foo", "hello@world.com");
user = users.save(user);
Shoebox sb = new Shoebox(user, "Name", "Context", "Comment", false);
UUID sbId = shoeboxes.save(sb).getId();
sb = shoeboxes.findOne(sbId);
assertNotNull(sb);
assertEquals(sb.getName(), "Name");
assertEquals(sb.getContext(), "Context");
assertEquals(sb.getComment(), "Comment");
assertEquals(sb.isShare(), false);
shoeboxes.deleteById(sbId);
users.deleteById(userId);
}
然而当它得到它时抛出一个
integrity constraint violation: unique constraint or index violation; SYS_PK_10126 table: USER
尝试将鞋盒保存到数据库时出现异常。它成功地保留了用户,并且在没有所有者 FK 附加到它时成功地保留了 Shoebox 对象,但在提供 FK 时崩溃。
这是我的用户 POJO:
@Entity
@Table(name="User")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User implements Serializable
{
@Id
@Column(name = "ID")
private long ID;
@Column(name = "Name")
private String name;
@Column(name = "Email")
private String email;
@OneToOne(fetch = FetchType.LAZY)
private Shoebox currentlySelectedBox;
@OneToMany(fetch = FetchType.LAZY)
@JsonManagedReference(value="shoebox_owner")
private List<Shoebox> shoeboxes;
// Contructors, Getters/Setters etc.
}
还有我的鞋盒 POJO:
@Entity
@Table(name="Shoebox")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Shoebox implements Serializable
{
@Id
@Column(name="ID")
UUID ID;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="OwnerID")
@JsonBackReference(value="shoebox_owner")
User owner;
@Column(name="Name")
String name;
@Column(name="Context")
String context;
@Column(name="Comment")
String comment;
@Column(name="Shared")
boolean share;
@Column(name="CreationDate")
LocalDateTime creationDate;
// Contructors, Getters/Setters etc.
}
这是数据库的 HSQL 创建脚本:
CREATE MEMORY TABLE PUBLIC.SHOEBOX(ID BINARY(255) NOT NULL PRIMARY KEY,COMMENT VARCHAR(255),CONTEXT VARCHAR(255),CREATIONDATE TIMESTAMP,NAME VARCHAR(255),SHARED BOOLEAN,OWNERID BIGINT)
CREATE MEMORY TABLE PUBLIC.USER(ID BIGINT NOT NULL PRIMARY KEY,EMAIL VARCHAR(255),NAME VARCHAR(255),CURRENTLYSELECTEDBOX_ID BINARY(255),CONSTRAINT FK3T924ODM2BIK5543K0E3UEGP FOREIGN KEY(CURRENTLYSELECTEDBOX_ID) REFERENCES PUBLIC.SHOEBOX(ID))
CREATE MEMORY TABLE PUBLIC.USER_SHOEBOX(USER_ID BIGINT NOT NULL,SHOEBOXES_ID BINARY(255) NOT NULL,CONSTRAINT FK5W8WMFC5E9RMEK7VC4N76MQVQ FOREIGN KEY(SHOEBOXES_ID) REFERENCES PUBLIC.SHOEBOX(ID),CONSTRAINT FKIR9SOKRCOQ33LCQTNR0LDXO93 FOREIGN KEY(USER_ID) REFERENCES PUBLIC.SHOEBOXUSER(ID),CONSTRAINT UK_508XA86IDIHP04FQD3D6GF8D7 UNIQUE(SHOEBOXES_ID))
ALTER TABLE PUBLIC.SHOEBOX ADD CONSTRAINT FK3J9RQBYW5VQ0IRF3FWYPG7LAB FOREIGN KEY(OWNERID) REFERENCES PUBLIC.USER(ID)
为什么会触发异常?我的注释和对象之间的 PK/FK 关系有问题吗?
非常感谢。
问题是
@ManyToOne(cascade = CascadeType.ALL)
使用CascadeType.ALL
,任何操作都将扩展到其他实体。所以在这种情况下,保存方法级联在鞋盒的用户试图再次保存它。由于您使用的是 1
的静态 ID,因此会导致键约束。