JPA CascadeType Persist不适用于spring数据 [英] JPA CascadeType Persist doesn't work with spring data
问题描述
我有两个实体,用户:
@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;
}
然后我用这种方法保存这些实体:
And I save these entities in this method:
@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持久不起作用,它引发以下异常:
But CascadeType persist doesn't work, it throws the following exception:
org.postgresql.util.PSQLException: ERROR: null value in column "user_id" violates not-null constraint
Подробности: Failing row contains (Oda2AolKrQXYSxuVmclO, null).
但是当我将层叠类型更改为MERGE时,它可以工作.而且我不明白为什么,因为我同时创建了新用户和新验证.首先,我需要保存用户,然后进行验证.你知道答案吗?
But when I change cascade type to MERGE, it works. And I don't understand why, because I create new User and new Verification at the same time. And first I need to save the user, then the verification. Do you know the answer?
推荐答案
Spring Data JPA使用ID来确定实例是否为新实例.既然您似乎将id设置为非空值,那么Spring Data JPA会将其视为现有实体,并调用merge
而不是persist
.
Spring Data JPA uses the ID to determine if the instance is new or not. Since it seems you are setting the id to a non-null value Spring Data JPA considers it an existing entity and calls merge
instead of persist
.
阅读参考文档中的保存实体" 有关如何调整该行为.
Read "Saving Entities" in the Reference Documentation about how to tweak that behavior.
我建议从域驱动设计和聚合/聚合根的角度进行思考,以便确定应通过Cascade.ALL
+ DELETE_ORPHAN
链接的实体以及那些没有任何级联和独立存储库的实体.
I recommend thinking in terms of Domain Driven Design and Aggregates/Aggregate Roots in order to determine the entities which should be linked via Cascade.ALL
+ DELETE_ORPHAN
and those without any cascading and separate repositories instead.
我建议阅读有关该主题的"推进企业DDD ".
I recommend reading "Advancing Enterprise DDD" about the topic.
这篇关于JPA CascadeType Persist不适用于spring数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!