I'm writting my application using Spring MVC. I want to validate is e-mail exists in database when user is registering. I've written my own annotation constraint named UniqueEmail.
My User entity User.java:
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "email", length = 100, nullable = false, unique = true)
@NotEmpty
@Email
@UniqueEmail(message = "E-mail is not unique")
private String email;
@Column(name = "password", nullable = false)
@NotEmpty
@Size(min = 5, message = "size must be more 5")
private String password;
}
My annotation constraint UniqueEmail.java:
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueEmailValidator.class)
@Documented
public @interface UniqueEmail {
String message() default "Email is exist";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
My validator UniqueEmailValidator.java:
@Component
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
@Autowired
private UserService userService;
@Override
public void initialize(UniqueEmail uniqueEmail) {
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
try {
return userService.isExistEmail(s);
} catch (Exception e) {
System.out.println(e);
return false;
}
}
}
This code works in application.
When I run my test code its return NullPointerException. In my validation class userService is null.
I've read http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html but cannot any solution.
Any idea?
Update
I use JUnit. UserClassTest.java
@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
public class UserClass {
private static Validator validator;
@BeforeClass
public static void setup() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
@Test
public void emailIsUnique() {
User user = new User();
user.setEmail("[email protected]"); // I've written exist email in DB.
Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "email");
assertEquals(1, constraintViolations.size());
assertEquals("E-mail is not unique", constraintViolations.iterator().next().getMessage());
}
}
Update
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="ru.yadoka"/>
<import resource="db/db-config.xml"/>
<!-- Apache tiles -->
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
</bean>
<!-- Mapping resources from theme -->
<mvc:resources mapping="/css/**" location="/resources/css/"/>
<mvc:resources mapping="/js/**" location="/resources/js/"/>
<mvc:resources mapping="/fonts/**" location="/resources/
<mvc:annotation-driven/>
Don't you have a Validator configured in your bean context. If you are bootstrapping Validator via Validation.buildDefaultValidatorFactory(); you are bypassing the Spring mechanism and you get a Validator which is not aware of Spring beans and components. Hence injection is not working. In your test you want to get hold of the Spring provided Validator.
You can call injection all @Autowired service:
@Override
public void initialize(UniqueEmail uniqueEmail) {
org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With