[英]Hibernate validator causing many to many relationship to not save
I have a ManyToMany relationship between User and Role. 我在用户和角色之间有ManyToMany关系。 I have a custom hibernate validation constraint on my roles Set in User.
我对用户中的角色设置有一个自定义的休眠验证约束。
In a @PostConstruct
I save the initial roles (ADMIN, USER) to the database using standard JpaRepository from spring-data-jpa. 在
@PostConstruct
我使用spring-data-jpa中的标准JpaRepository将初始角色(ADMIN,USER)保存到数据库中。 I then create an initial user using the admin role. 然后,我使用admin角色创建一个初始用户。
If I do not have my custom validation, the association is saved correctly and I see an entry in user_role
join table. 如果没有自定义验证,则关联将正确保存,并且在
user_role
连接表中看到一个条目。 If I have the validation, the user is inserted into the user table, but without an entry into user_role
table. 如果我有验证,则将用户插入到用户表中, 但没有到
user_role
表中的条目。 The returned entity has the role in the roles set, but it is not saved into the DB. 返回的实体在角色集中具有该角色,但不会保存到数据库中。 The code is summarized below.
该代码总结如下。 I cannot understand how using the RoleRepo to fetch all of the roles could in any way break the save, but it does.
我不明白如何使用RoleRepo来获取所有角色可能以任何方式破坏保存,但确实如此。
class User {
@Id
String username;
@ValidOption
@ManyToMany(cascade = {CascadeType.ALL //for example}, fetch=FetchType.EAGER)
Set<Role> roles;
}
class Role {
@Id
String name;
}
class CustomValidator implements ConstraintValidator<ValidOption, Object> {
RoleRepository roleRepo; //injected by spring... have spring factory
@Override
public boolean isValid(Object value, ConstraintValidatorContext context){
roleRepo.findAll() //<-------------- THIS CALL BREAKS THE SAVE
return true;
}
}
@Component
class UserCreator {
RoleRepository roleRepo;
UserRepo userRepo;
@PostConstruct
void setup(){
Role admin = roleRepo.saveAndFlush(new Role('ADMIN'));
roleRepo.saveAndFlush(new Role('USER'));
User user = new User('admin', Collections.singleton(admin));
userRepo.save(user); //<------ DOES NOT INSERT ADMIN INTO USER_ROLE JOIN TABLE
}
}
This works 100% exactly the way I would expect if I remove the custom validator. 这完全符合我删除自定义验证程序时的预期效果。 It may also work if I don't run this in PostConstruct and schedule it in a different thread, I need to check that.
如果我没有在PostConstruct中运行它并将它安排在另一个线程中,那么它也可能会起作用,我需要检查一下。
Project with reproducible failing test case: https://github.com/tjhelmuth/SPR-22533/blob/master/src/test/java/spr22533/bug/BugExample.java 具有可重现的失败测试用例的项目: https : //github.com/tjhelmuth/SPR-22533/blob/master/src/test/java/spr22533/bug/BugExample.java
Accessing the EntityManager
during validation is not guaranteed to work during validation. 验证期间不能保证在验证期间访问
EntityManager
。
Validation happens in "lifecycle callback methods". 验证发生在“生命周期回调方法”中。 For these the following restriction applies (Java Persistence Specification 2.2; Section 3.5.2 Lifecycle Callback Methods):
对于这些,以下限制适用(Java持久性规范2.2;第3.5.2节“生命周期回调方法”):
In general, the lifecycle method of a portable application should not invoke EntityManager or query operations, access other entity instances, or modify relationships within the same persistence context.
通常,便携式应用程序的生命周期方法不应调用EntityManager或查询操作,访问其他实体实例或修改同一持久性上下文内的关系。 A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.
生命周期回调方法可以修改在其上调用它的实体的非关系状态。
To make it work, use a separate EntityManager
, which of course might suffer from seeing a different set of changes since it runs a different transaction. 要使其工作,请使用单独的
EntityManager
,因为它运行不同的事务,因此当然可能会遇到一组不同的更改。
See also: Correct way to do an EntityManager query during Hibernate Validation 另请参阅: 在休眠验证期间执行EntityManager查询的正确方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.