java - JPA CascadeType Persist 不适用于 spring 数据
问题描述
我有两个实体,用户:
@Data
@EqualsAndHashCode(exclude = "id")
@Entity
@Table(name = "users")
public class User {
@Id
@SequenceGenerator(name = "user_id_seq_gen", sequenceName = "users_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq_gen")
private long id;
@Column(nullable = false, unique = true, length = 100)
@NotNull
@Length(min = 4, max = 100)
private String email;
@Column(nullable = false, length = 50)
@NotNull
@Length(min = 6, max = 100)
private String password;
}
和验证:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Verification {
@Id
@Column(length = 20)
private String code;
@OneToOne(cascade = {CascadeType.PERSIST})
private User user;
}
我用这种方法保存这些实体:
@Transactional
public void registerUser(User user) {
user.setPassword(DigestUtils.md5Hex(user.getPassword()));
String code = RandomStringUtils.random(20, true, true);
Verification verification;
while(true) {
if (!verificationRepository.existsByCode(code)) {
verification = new Verification(code, user);
break;
} else {
code = RandomStringUtils.random(20, true, true);
}
}
verificationRepository.save(verification);
}
但是 CascadeType persist 不起作用,它会抛出以下异常:
org.postgresql.util.PSQLException: ERROR: null value in column "user_id" violates not-null constraint
Подробности: Failing row contains (Oda2AolKrQXYSxuVmclO, null).
但是当我将级联类型更改为 MERGE 时,它可以工作。而且我不明白为什么,因为我同时创建了新用户和新验证。首先我需要保存用户,然后是验证。你知道答案吗?
解决方案
Spring Data JPA 使用 ID 来确定实例是否是新的。由于您似乎将 id 设置为非空值 Spring Data JPA 将其视为现有实体并调用merge
而不是persist
.
阅读参考文档中的“保存实体”,了解如何调整该行为。
我建议考虑领域驱动设计和聚合/聚合根,以确定应该通过Cascade.ALL
+链接的实体DELETE_ORPHAN
以及没有任何级联和单独存储库的实体。
我建议阅读有关该主题的“ Advancing Enterprise DDD ”。
推荐阅读
- php - 无法检索 POST 数据
- node.js - 在 node-sass@4.7.2 安装后脚本失败
- javascript - express app ENOENT: no such file or directory ajax call 500 internal server error
- javascript - 如何在 jQuery 上附加 [string] [jquery object] [string]
- java - BroadcastReceveir 不适用于蓝牙
- machine-learning - Rasa NLU Trainer-如何修复“找不到训练文件”错误?
- python - 错误导入白噪声
- javascript - 如何向表中添加键
- java - 如何通过在 Java 中调用 Windows API 来打开 DVD 驱动器?
- reactjs - Apollo GraphQL Client (ReactJS) - 在 graphql 查询中访问 props