Reputation: 381
I'm trying to create custom bean validation using annotations and ConstraintValidator interface. The purpose is to make model's name unique. I don't know why, but when I'm submitting form in order to add a product NullPointerException is thrown.
java.lang.NullPointerException
pl.dsdev.validator.UniqueNameValidator.isValid(UniqueNameValidator.java:20)
Model class:
@Entity
public class Product {
@Id
@GeneratedValue
private long id;
@NotNull(message = "Name is required")
@Size.List({@Size(min = 3, message = "must be longer than {min} characters"), @Size(max = 25, message = "must be shorter than {max} characters")})
@UniqueName(message = "This name is used by another product.")
private String name;
Annotation interface:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueNameValidator.class)
public @interface UniqueName {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Implementation of ConstraintValidator:
public class UniqueNameValidator implements ConstraintValidator<UniqueName, String> {
@Autowired
private ProductService productService;
public void initialize(UniqueName uniqueName) {
}
public boolean isValid(String name, ConstraintValidatorContext constraintValidatorContext) {
return productService.findByName(name)==null;
}
public ProductService getProductService() {
return productService;
}
public void setProductService(ProductService productService) {
this.productService = productService;
}
}
My root-context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<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" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="pl.dsdev" />
<mvc:annotation-driven />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/springbaza" />
<property name="username" value="tutorial" />
<property name="password" value="password" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="pl.dsdev.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="validation"/>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
Upvotes: 0
Views: 821
Reputation: 12446
It looks like your productService
is not being injected by spring (this explains NPE you are getting).
You have either misconfigured (or not configured at all) spring bean validation.
Upvotes: 2