我尝试创建我的验证批注。
当验证失败时,它会很好地工作。我收到一条消息。但是当验证通过时,我得到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] o.h.i.ExceptionMapperStandardImpl:HHH000346:发生错误 托管刷新[HV000028:isValid调用期间发生意外异常。 2019-07-07 13:14:09.777错误11680 --- [io-8080-exec-10] o.a.c.c.C。[。[。[/]。[dispatcherServlet]:的Servlet.service() 路径[]中的servlet [dispatcherServlet]抛出异常 [请求处理失败;嵌套异常为 org.springframework.transaction.TransactionSystemException:无法 进行JPA交易;嵌套异常为 javax.persistence.RollbackException:提交错误 交易]的根本原因
java.lang.NullPointerException:为null ru.project.domain.validation.UniqueEmailValidator.isValid(UniqueEmailValidator.java:17) 〜[classes /:na]在 ru.project.domain.validation.UniqueEmailValidator.isValid(UniqueEmailValidator.java:1) 〜[classes /:na]在 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尝试保存新用户时。
我将展示每次调试器向我显示的内容。
更新:isEmailAlreadyUse:
public boolean isEmailAlredyUse(String value) {
User user = userRepository.findByEmail(value);
if(user != null) {
return true;
}
return false;
}
答案 0 :(得分:0)
尝试一下:
@Email(message="Please provide a valid email address")
@Pattern(regexp=".+@.+\\..+", message="Please provide a valid email address")
@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface ExtendedEmailValidator {
String message() default "Please provide a valid email address";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
如何使用?在您的实体中添加以下内容:
@Column
@ExtendedEmailValidator(message = "custom message")
private String email;
在您的@Controller
中,尝试以下操作:
@PostMapping
public ModelAndView createNewUser(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
User userExists = userService.findUserByEmail(user.getEmail());
if (userExists != null) {
bindingResult
.rejectValue("email", "error.user",
"There is already a user registered with the email provided");
}
if(bindingResult.hasErrors()){
modelAndView.setViewName("registration");
return modelAndView;
}
/*
Other code
*/
}
答案 1 :(得分:0)
一个决定是在“休眠”状态下将实体保存到数据库中时关闭检查。为此,您需要在application.properties
中设置下一个属性。spring.jpa.properties.javax.persistence.validation.mode =无