hai*_*one 1 spring hibernate autowired bean-validation
我刚刚用Hibernate实现了Bean Validation.
如果我显式调用验证器它按预期工作,并且按预期注入连接到DB的@Autowired DAO bean.
我以前发现我需要在上面的内容之前添加以下语句.之前我已经广泛使用了@Autowired bean,但下面的语句对于由Spring管理验证器和注入ConstraintValidator的bean是必要的.
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
Run Code Online (Sandbox Code Playgroud)
但是,当在SessionFactory.getCurrentSession.merge期间自动调用验证器时,bean为null.
如果我通过调用javax.Validation.validate直接调用验证器,它的工作原理使我认为我已正确设置了Spring配置.
我已经读过人们无法获得DAO bean @Autowired的帖子的数字,但在我的情况下,除了在合并期间调用时.
下面的日志输出显示首先直接调用验证器,然后作为合并操作的结果调用.
07.12.2011 01:58:13 INFO [http-8080-1] (FileTypeAndClassValidator:isValid) - Validating ...
07.12.2011 01:58:13 INFO [http-8080-1] (ConstraintValidatorHelper:getPropertyValue) - propertyName=className, returnValue=com.twoh.dto.PurchaseOrder
07.12.2011 01:58:13 INFO [http-8080-1] (ConstraintValidatorHelper:getPropertyValue) - propertyName=fileTypeId, returnValue=4
07.12.2011 01:58:13 INFO [http-8080-1] (QueryUtil:createHQLQuery) - select ft.id from FileType ft where ft.id = :fileTypeId and ft.fileClassName = :fileClassName
07.12.2011 01:58:13 INFO [http-8080-1] (BaseDAO:merge) - Entity: com.twoh.dto.PurchaseOrder: 1036.
07.12.2011 01:58:13 INFO [http-8080-1] (FileTypeAndClassValidator:isValid) - Validating ...
07.12.2011 01:58:13 INFO [http-8080-1] (ConstraintValidatorHelper:getPropertyValue) - propertyName=className, returnValue=com.twoh.dto.PurchaseOrder
07.12.2011 01:58:13 INFO [http-8080-1] (ConstraintValidatorHelper:getPropertyValue) - propertyName=fileTypeId, returnValue=4
07.12.2011 01:58:13 INFO [http-8080-1] (FileTypeAndClassValidator:isValid) - java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)
以下是ConstraintValidator的代码:
package com.twoh.dto.ConstraintValidation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.twoh.dao.IQueryUtil;
@Component
public class FileTypeAndClassValidator implements ConstraintValidator<FileTypeAndClass, Object> {
private Log logger = LogFactory.getLog(this.getClass());
private String fileClassProperty;
private String fileTypeProperty;
@Autowired
private IQueryUtil queryUtil;
public void initialize(FileTypeAndClass constraintAnnotation) {
this.fileClassProperty = constraintAnnotation.fileClassProperty();
this.fileTypeProperty = constraintAnnotation.fileTypeProperty();
}
public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
boolean result = true;
logger.info("Validating ...");
if (object == null) {
result = false;
} else {
try {
String fileClassName = ConstraintValidatorHelper.getPropertyValue(String.class, fileClassProperty, object);
Integer fileTypeId = ConstraintValidatorHelper.getPropertyValue(Integer.class, fileTypeProperty, object);
result = queryUtil.createHQLQuery((
"select ft.id" +
" from FileType ft" +
" where ft.id = :fileTypeId" +
" and ft.fileClassName = :fileClassName"
))
.setParameter("fileTypeId", fileTypeId)
.setParameter("fileClassName", fileClassName)
.iterate().hasNext();
} catch (Exception e) {
logger.info(e);
}
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
大约18小时的谷歌搜索后,我终于遇到了一个网站,它都描述了它有解决方案的问题.配方:使用基于事件的Hibernate验证与自定义JSR-303验证器和Spring自动注入
在我当前的项目中,我们想要构建一个自定义验证器,在使用Hibernate保存Contact实体的任何实例之前,它将检查数据库中是否已存在电子邮件地址.此验证器需要注入DAO以检查数据库中是否存在电子邮件地址.令我们惊讶的是,我们认为微风更像是一场大风.当我们的bean在Hibernate基于事件的验证(在我们的例子中是插入前事件)的上下文中被验证时,Spring的注入根本不起作用.
最后,我的弹簧配置最终看起来像这样:
...
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="beanValidationEventListener" class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener">
<constructor-arg ref="validator"/>
<constructor-arg ref="hibernateProperties"/>
</bean>
...
<util:properties id="hibernateProperties" location="classpath:hibernate.properties"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.twoh" />
<property name="hibernateProperties" ref="hibernateProperties"/>
<property name="eventListeners">
<map>
<entry key="pre-insert" value-ref="beanValidationEventListener" />
<entry key="pre-update" value-ref="beanValidationEventListener" />
</map>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
从2.5.1开始,您可以使用Spring框架提供的以下方法
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
Run Code Online (Sandbox Code Playgroud)
它更清晰,因为您不必在整个应用程序中设置任何侦听器/属性.
你的代码看起来像这样:
public class ValidUniqueUserEmailValidator implements ConstraintValidator<ValidUniqueUserEmail, Object>, Serializable {
private static final long serialVersionUID = 1L;
@Autowired
private UserDAO userDAO;
@Override
public void initialize(ValidUniqueUserEmail constraintAnnotation) {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
boolean isValid = true;
if (value instanceof String) {
String email = value.toString();
if (email == null || email.equals("")) {
isValid = false;
}else{
User user = new User();
user.setEmail(email);
isValid = (userDAO.countByEmail(user) > 0);
}
}
return isValid;
}
}
Run Code Online (Sandbox Code Playgroud)
希望它可以帮助你们
| 归档时间: |
|
| 查看次数: |
4195 次 |
| 最近记录: |