我定义了@FuSsA_UniqueKey约束注释:
package com.fussa.employee.util;
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 = { UniqueIDValidator.class })
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface FuSsA_UniqueKey {
String columnNames();
String message() default "{Value is not unique}";
Class<?>[]groups() default {};
Class<? extends Payload>[]payload() default {};
}
定义了我的注释后,我创建了一个约束验证器 UniqueIDValidator ,它能够使用 @FuSsA_UniqueKey 注释验证元素:
package com.fussa.employee.util;
import java.io.Serializable;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder;
import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
public class UniqueIDValidator implements ConstraintValidator<FuSsA_UniqueKey, Serializable> {
@Autowired
private SessionFactory sessionFactory;
private Session s;
private String uniqueField;
private FuSsA_UniqueKey unique;
public void initialize(FuSsA_UniqueKey unique) {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
uniqueField = unique.columnNames();
}
@Override
public boolean isValid(Serializable arg0, ConstraintValidatorContext arg1) {
String a = arg0.getClass().getSimpleName();
String query = String.format("from %s where %s = :%s ", a, uniqueField, uniqueField);
List<?> list = null;
try {
s = sessionFactory.getCurrentSession();
s.setFlushMode(FlushMode.COMMIT);
list = s.createQuery(query).setParameter(uniqueField, "FuSsA").list();
} catch (HibernateException e) {
s = sessionFactory.openSession();
s.setFlushMode(FlushMode.COMMIT);
list = s.createQuery(query).setParameter(uniqueField, "FuSsA").list();
} finally {
// this is to reset the hibernate config I think
s.setFlushMode(FlushMode.AUTO);
}
if (list != null && !(list.size() > 1)) {
return true;
} else {
ConstraintViolationBuilder cvb = arg1.buildConstraintViolationWithTemplate(unique.message());
NodeBuilderDefinedContext nbdc = cvb.addNode(unique.columnNames());
ConstraintValidatorContext cvc = nbdc.addConstraintViolation();
cvc.disableDefaultConstraintViolation();
return false;
}
}
}
控制器上的 saveEmployee :
@Autowired
EmployeeService service;
@Autowired
MessageSource messageSource;
@Autowired
private Validator validator;
@RequestMapping(value = { "/new" }, method = RequestMethod.POST)
public String saveEmployee(@Valid Employee employee, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
Set<ConstraintViolation<Employee>> violations = validator.validate(employee);
if (!violations.isEmpty()) {
FieldError ssnError = new FieldError("employee", "ssn", messageSource.getMessage("non.unique.ssn",
new String[] { employee.getSsn() }, Locale.getDefault()));
result.addError(ssnError);
return "registration";
} else {
service.saveEmployee(employee);
model.addAttribute("success", "Employee " + employee.getName() + " registered successfully");
return "success";
}
}
我还添加到我的 @Configuration 类 AppConfig 这个方法,所以我可以在我的控制器上自动装配它“不确定它是否正确”:
@Bean
public Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
当我尝试保存我的对象时..我遇到了这个错误:
Caused by: javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:451)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:127)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:592)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:555)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:490)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:454)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:406)
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:204)
at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:108)
at org.springframework.validation.DataBinder.validate(DataBinder.java:866)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.validateIfApplicable(ModelAttributeMethodProcessor.java:164)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
... 31 more
Caused by: java.lang.NullPointerException
at com.fussa.employee.util.UniqueIDValidator.isValid(UniqueIDValidator.java:54)
at com.fussa.employee.util.UniqueIDValidator.isValid(UniqueIDValidator.java:1)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:448)
... 54 more
所以错误就在那一行:
ConstraintViolationBuilder cvb = arg1.buildConstraintViolationWithTemplate(unique.message());
感谢任何建议..
答案 0 :(得分:0)
我通过初始化变量唯一:
解决了这个问题public void initialize(FuSsA_UniqueKey unique) {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
this.unique = unique;
uniqueField = unique.columnNames();
}