我正在使用Hibernate / Spring Boot测试HSQL数据库的基础模型,而且我遇到了一个无法找到解决方案的问题。
这是我的简单测试,我试图创建一个鞋盒实体并将其保存到数据库中,并将User对象设置为所有者的FK:
@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);
}
然而当它得到它时会抛出一个
尝试将Shoebox保存到数据库时出现完整性约束违规:唯一约束或索引违规; SYS_PK_10126表: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.
}
我的Shoebox 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.
}
以下是DB的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关系有问题吗?
非常感谢。
答案 0 :(得分:2)
问题是
@ManyToOne(cascade = CascadeType.ALL)
使用CascadeType.ALL
,任何操作都将扩展到其他实体。因此,在这种情况下,保存方法在鞋盒的用户尝试再次保存时级联。由于您使用的是静态ID 1
,因此会导致键约束。