From 09fde31732cb380c1ac5783f75220119b3733e17 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 26 Feb 2015 18:33:53 +0100 Subject: [PATCH] Support for Hibernate Validator 5.2 Issue: SPR-12758 --- .../LocalValidatorFactoryBean.java | 13 +++++- .../ValidatorFactoryTests.java | 40 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 86d0026c4e7..913406f06da 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -222,6 +222,17 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter Validation.byProvider(this.providerClass).configure() : Validation.byDefaultProvider().configure()); + // Try Hibernate Validator 5.2's externalClassLoader(ClassLoader) method + if (this.applicationContext != null) { + try { + Method eclMethod = configuration.getClass().getMethod("externalClassLoader", ClassLoader.class); + ReflectionUtils.invokeMethod(eclMethod, configuration, this.applicationContext.getClassLoader()); + } + catch (NoSuchMethodException ex) { + // Ignore - no Hibernate Validator 5.2+ or similar provider + } + } + MessageInterpolator targetInterpolator = this.messageInterpolator; if (targetInterpolator == null) { targetInterpolator = configuration.getDefaultMessageInterpolator(); diff --git a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java b/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java index 03a42dff761..356e1a99de1 100644 --- a/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java +++ b/spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/ValidatorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,10 @@ import javax.validation.constraints.NotNull; import org.hibernate.validator.HibernateValidator; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; @@ -60,6 +64,7 @@ public class ValidatorFactoryTests { public void testSimpleValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set> result = validator.validate(person); assertEquals(2, result.size()); @@ -80,6 +85,7 @@ public class ValidatorFactoryTests { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set> result = validator.validate(person); assertEquals(2, result.size()); @@ -114,6 +120,7 @@ public class ValidatorFactoryTests { public void testSpringValidationFieldType() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Phil"); person.getAddress().setStreet("Phil's Street"); @@ -128,6 +135,7 @@ public class ValidatorFactoryTests { public void testSpringValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); validator.validate(person, result); @@ -155,6 +163,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithClassLevel() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Juergen"); person.getAddress().setStreet("Juergen's Street"); @@ -168,10 +177,30 @@ public class ValidatorFactoryTests { assertTrue(errorCodes.contains("NameAddressValid")); } + @Test + public void testSpringValidationWithAutowiredValidator() throws Exception { + ApplicationContext ctx = new AnnotationConfigApplicationContext(LocalValidatorFactoryBean.class); + LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class); + + ValidPerson person = new ValidPerson(); + person.expectsAutowiredValidator = true; + person.setName("Juergen"); + person.getAddress().setStreet("Juergen's Street"); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(1, result.getErrorCount()); + ObjectError globalError = result.getGlobalError(); + List errorCodes = Arrays.asList(globalError.getCodes()); + assertEquals(2, errorCodes.size()); + assertTrue(errorCodes.contains("NameAddressValid.person")); + assertTrue(errorCodes.contains("NameAddressValid")); + } + @Test public void testSpringValidationWithErrorInListElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressList().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -189,6 +218,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithErrorInSetElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressSet().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -242,6 +272,8 @@ public class ValidatorFactoryTests { @Valid private Set addressSet = new LinkedHashSet(); + public boolean expectsAutowiredValidator = false; + public String getName() { return name; } @@ -306,12 +338,18 @@ public class ValidatorFactoryTests { public static class NameAddressValidator implements ConstraintValidator { + @Autowired + private Environment environment; + @Override public void initialize(NameAddressValid constraintAnnotation) { } @Override public boolean isValid(ValidPerson value, ConstraintValidatorContext context) { + if (value.expectsAutowiredValidator) { + assertNotNull(this.environment); + } boolean valid = (value.name == null || !value.address.street.contains(value.name)); if (!valid && "Phil".equals(value.name)) { context.buildConstraintViolationWithTemplate(