首页 > 解决方案 > 当 userRepository 尝试在数据库中保存新用户时,我的验证器失败

问题描述

我尝试创建我的验证注释。

当验证失败时,它工作得很好。我收到一条消息。但是当验证通过时,我得到 RollbackException。

我在验证注释中做了什么?

我想检查用户表中的唯一电子邮件。因此,我创建了@annotation:

package ru.project.domain.validation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Constraint(validatedBy = UniqueEmailValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface UniqueEmail {

    public String message() default "e-mail exist!";

    public Class<?>[] groups() default {};

    public Class<? extends Payload>[] payload() default{};

}

我创建了验证器:

package ru.project.domain.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.springframework.beans.factory.annotation.Autowired;

import ru.project.service.UserService;

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {

    @Autowired
    private UserService userService;

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && !userService.isEmailAlredyUse(value);
    }

}

当我输入非唯一电子邮件时,我收到消息“电子邮件存在!”

但是当我输入唯一的电子邮件时,我收到错误:

2019-07-07 13:14:09.770 错误 11680 --- [io-8080-exec-10] ohiExceptionMapperStandardImpl:HHH000346:托管刷新期间出错 [HV000028:isValid 调用期间出现意外异常。] 2019-07-07 13:14 :09.777 错误 11680 --- [io-8080-exec-10] oaccC[.[.[/].[dispatcherServlet]:Servlet.service() 用于路径 [] 上下文中的 servlet [dispatcherServlet] 引发异常 [请求处理失败的; 嵌套异常是 org.springframework.transaction.TransactionSystemException:无法提交 JPA 事务;嵌套异常是 javax.persistence.RollbackException: Error while committing the transaction] 根本原因

java.lang.NullPointerException: null at ru.project.domain.validation.UniqueEmailValidator.isValid(UniqueEmailValidator.java:17) ~[classes/:na] at ru.project.domain.validation.UniqueEmailValidator.isValid(UniqueEmailValidator.java: 1) ~[classes/:na] at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:171) ~[hibernate-validator-6.0.17.Final.jar:6.0.17. Final] 在 org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:68) ~[hibernate-validator-6.0.17.Final.jar:6.0.17.Final] 在 org.hibernate。 validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:73) ...

函数 isValid 被调用两次。在表单上的按钮后验证以及 userRepository 尝试保存新用户时。

我将展示调试器每次显示的内容。

当表单上的按钮(唯一的电子邮件): 在此处输入图像描述

当 userRepository 尝试保存新用户时: 在此处输入图像描述

更新: isEmailAlreadyUse:

public boolean isEmailAlredyUse(String value) {
        User user = userRepository.findByEmail(value);
        if(user != null) {
            return true;
        }
        return false;
    }

在第二次运行 userService = null 期间: 在此处输入图像描述

标签: springhibernatespring-bootvalidation

解决方案


一个决定是在“休眠”将实体保存在数据库中时关闭检查。为此,您需要在 application.properties 中设置下一个属性

spring.jpa.properties.javax.persistence.validation.mode=none


推荐阅读