【发布时间】:2018-04-14 20:18:02
【问题描述】:
我试图在我的 Spring Boot 应用程序中引入一个基本实体,但现在 Hibernate 插入了重复的条目。该应用使用 Spring Data JPA 和 Hibernate 进行持久化。
我之前的代码是这样的:
@Entity
public class PasswordResetCode {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
private User user;
@Column(unique = true)
private String code;
public PasswordResetCode(User user, String code) {
this.user = user;
user.addPasswordResetCode(this);
this.code = code;
}
// ...
}
@Entity
@Table(name = "\"user\"")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
private Set<PasswordResetCode> passwordResetCodes = new HashSet<>();
public void addPasswordResetCode(PasswordResetCode passwordResetCode) {
this.passwordResetCodes.add(passwordResetCode);
}
// ...
}
我这样创建 PasswordResetCode:
User user = userRepository.findOne(id);
passwordResetCodeRepository.save(new PasswordResetCode(user, "some code"));
这工作得很好,PasswordResetCode 只被插入到数据库中一次,用户对象Set 中的引用被持久化的PasswordResetCode 更新。
现在我引入了BaseEntity,从User 和PasswordReset 类中删除了id 字段,并让它们扩展BaseEntity。
BaseEntity 看起来像这样:
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id = 0;
// getter & setter
}
我像以前一样创建了PasswordResetCode,但现在我收到以下错误,因为 Hibernate 尝试插入代码两次:
无法执行语句; SQL [不适用];约束 [“UK_JIAB2A9LLEHA81LWDNYRL9RQ0_INDEX_2 ON PUBLIC.PASSWORD_RESET_CODE(CODE) VALUES ('some code', 115)"
现在我意识到我可以删除User 中的级联或通过User/UserRepository 保存PasswordResetCode,但我想了解发生了什么。
为什么 Hibernate 可以看到 User 集合中的 PasswordResetCode 与他通过存储库保存的相同,尽管它是在持久化之前添加的?
还有为什么加了BaseEntity之后会失败?
【问题讨论】:
标签: java hibernate spring-boot jpa spring-data-jpa