Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 休眠验证程序导致多对多关系无法保存_Java_Spring_Hibernate_Spring Data Jpa_Hibernate Validator - Fatal编程技术网

Java 休眠验证程序导致多对多关系无法保存

Java 休眠验证程序导致多对多关系无法保存,java,spring,hibernate,spring-data-jpa,hibernate-validator,Java,Spring,Hibernate,Spring Data Jpa,Hibernate Validator,我在用户和角色之间有很多关系。我在User中设置的角色上有一个自定义hibernate验证约束 在@PostConstruct中,我使用spring数据jpa中的标准JpaRepository将初始角色(管理员、用户)保存到数据库中。然后,我使用admin角色创建一个初始用户 如果我没有自定义验证,则关联会正确保存,并且我会在user\u rolejoin表中看到一个条目。如果我有验证,则将用户插入到用户表中,但在用户角色表中没有条目。返回的实体在角色集中有角色,但不会保存到数据库中。代码摘要如

我在用户和角色之间有很多关系。我在User中设置的角色上有一个自定义hibernate验证约束

@PostConstruct
中,我使用spring数据jpa中的标准JpaRepository将初始角色(管理员、用户)保存到数据库中。然后,我使用admin角色创建一个初始用户

如果我没有自定义验证,则关联会正确保存,并且我会在
user\u role
join表中看到一个条目。如果我有验证,则将用户插入到用户表中,但在
用户角色
表中没有条目。
返回的实体在角色集中有角色,但不会保存到数据库中。代码摘要如下。我无法理解使用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
  }
}
类用户{
@身份证
字符串用户名;
@有效剂量
@ManyToMany(cascade={CascadeType.ALL//example},fetch=FetchType.EAGER)
设定角色;
}
阶级角色{
@身份证
字符串名;
}
类CustomValidator实现ConstraintValidator{
RoleRepository roleRepo;//由弹簧注射……拥有弹簧工厂
@凌驾
公共布尔值有效(对象值、ConstraintValidatorContext上下文){

roleRepo.findAll()//在验证期间访问
EntityManager
不保证在验证期间工作

验证发生在“生命周期回调方法”中。 对于这些方法,以下限制适用(Java持久性规范2.2;第3.5.2节生命周期回调方法):

通常,可移植应用程序的生命周期方法不应调用EntityManager或查询操作、访问其他实体实例或修改同一持久性上下文中的关系。生命周期回调方法可能会修改调用它的实体的非关系状态

要使其正常工作,请使用一个单独的
EntityManager
,因为它运行的是不同的事务,因此可能会看到不同的更改集


另请参见:

您有一些输出给我们吗?我不清楚“中断保存”。没有异常的负输出。我在描述中粗体显示了负输出。用户保存到“用户”表中,但没有插入到用户角色联接表中。我从“保存”返回的实体call中有管理员角色,但它不会保存在DB中。好的,谢谢你,我唯一的问题是我非常喜欢你使用spring数据的工作,并且希望像平常一样使用我的JpaRepository实现。如果我在验证器中分叉一个新线程,我能得到一个新的EM和JpaRepository实例吗?谢谢你的好话。Starti创建一个新线程可能会工作,但感觉有点不对劲。我想知道是否可以为验证器创建一个专用的作用域。或者可以通过编程方式构建存储库。当然,根据您在验证器中实际想要做的事情,只需创建一个新的
EntityManager
并直接使用它可能更容易。如果你有兴趣探索其他选择,请提出一个新问题,因为完整的答案不适合评论。