【发布时间】:2011-03-04 10:39:13
【问题描述】:
我正在尝试在 Spring 3.0.x 下编写自己的 Validator(根据 JSR-303 规范)。
我用@Transactional 注释了isValid(Serializable, CosntraintValidatorContext) 方法,但似乎事务建议没有应用于此方法 - 当调用isValid() 方法时,调用sessionFactory.getCurrentSession() 会创建异常:
org.hibernate.HibernateException: No Hibernate Session bound to thread,并且配置不允许在这里创建非事务性会话
我在同一个Validator bean 中有一个@Autowired sessionFactory,它被注入没有问题。我目前的解决方法是使用openSession() 而不是getCurrentSession(),但这涉及到我希望避免的手动事务管理。
在我的验证器 bean 的构造函数中进行堆栈跟踪,似乎我的 Validator bean 是通过调用 o.s.b.f.s.AbstractAutowireCapableBeanFactory.createBean() 构建的。我认为这意味着工厂能够在我的Validator 中填充@Autowired 字段,但它似乎没有应用任何事务建议?
在此先感谢您提供有关此问题的任何帮助。
编辑:如果有任何帮助,我在构造函数中包含了一个部分堆栈跟踪(通过create new Exception()):
at com.mydomain.validators.UniqueValidator.<init>(UniqueValidator.java:49) ~[UniqueValidator.class:na]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.6.0_20]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [na:1.6.0_20]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [na:1.6.0_20]
at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [na:1.6.0_20]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:74) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:958) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:286) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory.getInstance(SpringConstraintValidatorFactory.java:50) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.hibernate.validator.engine.ConstraintTree.createAndInitializeValidator(ConstraintTree.java:192) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ConstraintTree.getInitializedValidator(ConstraintTree.java:171) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:113) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.java:121) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:334) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForRedefinedDefaultGroup(ValidatorImpl.java:278) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:260) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:213) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:119) [hibernate-validator-4.0.2.GA.jar:4.0.2.GA]
at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:86) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.validation.DataBinder.validate(DataBinder.java:692) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:807) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:359) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
事务配置似乎是正确的(STS IDE 报告org.springframework.transaction.interceptor.TransactionInterceptor.invoke 事务管理器正确建议了isValid() 方法(在验证器本身上带有@Component 注释)),但我的理解是如果验证 bean 是在 Spring 容器的正常生命周期之外创建的,那么在数据绑定期间完成验证时将不会正确应用通知。
【问题讨论】:
-
你有非常有趣的堆栈跟踪:) 你能提示如何将包信息添加到每一行吗?谢谢。
标签: java spring spring-aop hibernate-validator bean-validation