我已经和它斗争了好几天,我已经阅读了所有的讨论,但没有解决方案...
我有自定义约束..
Unique.java
@Target({FIELD, METHOD})
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueConstraintValidator.class)
public @interface Unique {
String message() default "{src.main.resources}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String property() default "id";
Class<?> entity();
}
UniqueConstraintValidator.java
使用它@Transactional
public class UniqueConstraintValidator implements ConstraintValidator<Unique, Serializable> {
private static final Logger logger = Logger.getLogger(UniqueConstraintValidator.class);
Session session;
@Autowired
private SessionFactory sessionFactory;
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
private Class<?> entityClass;
private String uniqueField;
public void initialize(Unique unique) {
entityClass = unique.entity();
uniqueField = unique.property();
}
@SuppressWarnings("rawtypes")
public boolean isValid(Serializable property, ConstraintValidatorContext cvContext) {
String query = String.format("from %s where %s = :field ", entityClass.getName(), uniqueField);
List list = getSession().createQuery(query).setParameter("field", property).list();
return list != null && list.size() == 0;
}
}
现在,我的模型有这个注释,我需要验证字段的唯一性
@NotNull
@Unique(entity = Luce.class, property="numeroLuce")
@Column(name="numero_luce")
public int getNumeroLuce() {
return numeroLuce;
}
public void setNumeroLuce(int numeroLuce) {
this.numeroLuce = numeroLuce;
}
现在,我知道自定义注释在更新现有对象时不起作用,但现在我需要了解它是如何工作的。 我们假设我们要添加一个新对象。
当我尝试保存已存在的值时,我得到了正确的验证错误但是如果我想保存一个有效的对象,我得到了java.lang.NullPointerException
已编辑这是完整的堆栈跟踪
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:286)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:133)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:83)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:547)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:487)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:451)
org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:403)
org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:206)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:137)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:95)
org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:214)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:92)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:490)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:195)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:214)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
it.besmart.dao.AbstractDao.persist(AbstractDao.java:37)
it.besmart.dao.LuceDaoImpl.saveLuci(LuceDaoImpl.java:33)
it.besmart.service.LuceServiceImpl.saveLuci(LuceServiceImpl.java:33)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy48.saveLuci(Unknown Source)
it.besmart.controller.LuceController.saveLight(LuceController.java:87)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NullPointerException
it.besmart.validator.UniqueConstraintValidator.getSession(UniqueConstraintValidator.java:27)
it.besmart.validator.UniqueConstraintValidator.isValid(UniqueConstraintValidator.java:44)
it.besmart.validator.UniqueConstraintValidator.isValid(UniqueConstraintValidator.java:18)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:283)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:133)
org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:83)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:547)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:487)
org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:451)
org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:403)
org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:206)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:137)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:95)
org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:214)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:92)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:490)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:195)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:214)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
it.besmart.dao.AbstractDao.persist(AbstractDao.java:37)
it.besmart.dao.LuceDaoImpl.saveLuci(LuceDaoImpl.java:33)
it.besmart.service.LuceServiceImpl.saveLuci(LuceServiceImpl.java:33)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy48.saveLuci(Unknown Source)
it.besmart.controller.LuceController.saveLight(LuceController.java:87)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
我真的无法理解我做错了什么,我知道我是一个java noob,但一切看起来都是正确的。
我在 UniqueConstraintValidator 中添加了一个日志,以检查sessionFactory是否为null,但我还是
Session is org.hibernate.internal.SessionFactoryImpl@53911200
所以,它不是空的......
提前致谢
答案 0 :(得分:0)
在这个评论中你会找到答案。
JSR303 custom validators being called twice
首先按照弹簧在表单创建时验证对象,第二次在持久化之前通过休眠验证对象(默认行为)。据我所知,hibernate在Spring上下文之外进行验证,因此Autowired不起作用。这就是你得到NullPointerException的原因。
答案 1 :(得分:0)
通过此行:
it.besmart.validator.UniqueConstraintValidator.getSession(UniqueConstraintValidator.java:27)
这是说getSession()
抛出了NPE。我想getSession()
(如果是第27行)找不到sessionFactory
。 @Autowired
在这里不起作用。
而且,我实际上对将验证器与业务逻辑混合在一起的决定表示怀疑;当输入值正确时,验证器应返回true
;如果输入值不好,则验证器应返回false
;而已。您不应使其@Transactional
并将其保存到数据库中。不,代码有异味。