自定义约束验证调用isValid两次,抛出NullPointerException

时间:2017-03-28 18:24:43

标签: java spring hibernate spring-mvc jpa

我创建了一个自定义约束验证器,我用它来检查用户名上的验证,验证器正在访问数据库并检查记录是否已经存在以及它是否符合正则表达式。我得到了相当奇怪的错误,因为如果用户名已经存在,验证器工作正常,但输入有效输入(不存在的用户名)时会抛出NullPointerException。

我已经放置了一个计数器和一些语句,让我跟踪应用程序崩溃的位置,我将在堆栈跟踪中包含这些内容。应用程序似乎两次调用initialiseisValid方法,第二次抛出NullPointer。我查看了this question,其中将<property name="javax.persistence.validation.mode" value="none"/>添加到我的persistence.xml文件中,我已经完成并且没有做任何更改。

我想也许我必须在其他地方禁用它,因为我没有使用我的persistence.xml来配置应用程序,而是使用jpaContext.xml文件。

如果有人对hoot fix /我应该寻找修复的任何建议/先前经验我会很感激。

自定义约束验证程序

public class UserNameConstraintValidator implements ConstraintValidator<UserName, String> {
@Autowired
private HouseholdService householdService;

private int counter = 0;


public void initialize(UserName userName) {
    System.out.println("counter inside initialize is at count : " + counter);
}

public boolean isValid(String userName, ConstraintValidatorContext cxt) {
    System.out.println(userName);
    counter ++;
    System.out.println("counter is at count : " + counter);

    if(householdService.checkForUser(userName) || userName == null) {      //line 26
        System.out.println(userName);
        System.out.println("counter inside if statement is at count : " + counter);
        return false;
    }
    else {
        System.out.println(userName);
        System.out.println("counter inside else statement is at count : " + counter);
        return (userName.matches("^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$"));
    }
}
}

栈跟踪

        counter inside initialize is at count : 0
        newUser
        counter is at count : 1
        Tue Mar 28 19:18:23 BST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
        Mar 28, 2017 7:18:23 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
        INFO: HHH000397: Using ASTQueryTranslatorFactory
        Hibernate: select household0_.id as id1_1_, household0_.password as password2_1_, household0_.userName as userName3_1_ from Households household0_ where household0_.userName like ? limit ?
        Hibernate: select household0_.id as id1_1_, household0_.password as password2_1_, household0_.userName as userName3_1_ from Households household0_ where household0_.userName like ? limit ?
        inside HouseholdRepository, if statement has returned : 0
        newUser
        counter inside else statement is at count : 1
        Tue Mar 28 19:18:24 BST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
        Tue Mar 28 19:18:24 BST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
        Hibernate: select next_val as id_val from hibernate_sequence for update
        Hibernate: update hibernate_sequence set next_val= ? where next_val=?
        counter inside initialize is at count : 0
        newUser
        counter is at count : 1
        Mar 28, 2017 7:18:24 PM org.apache.catalina.core.StandardWrapperValve invoke
        SEVERE: Servlet.service() for servlet [springDispatcherServlet] in context with path [/Bill_Calculator] threw exception [Request processing failed; nested exception is javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.] with root cause
        java.lang.NullPointerException
            at com.chrishammer.view.UserNameConstraintValidator.isValid(UserNameConstraintValidator.java:26)
            at com.chrishammer.view.UserNameConstraintValidator.isValid(UserNameConstraintValidator.java:1)
            at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:446)
            at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:127)
            at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87)
            at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:616)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:581)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:527)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:495)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:460)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:410)
            at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:207)
            at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:116)
            at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80)
            at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
            at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
            at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:586)
            at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:460)
            at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
            at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
            at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1428)
            at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
            at com.sun.proxy.$Proxy36.flush(Unknown Source)
            at com.chrishammer.repository.HouseholdRepositoryImpl.save(HouseholdRepositoryImpl.java:23)
            at com.chrishammer.service.HouseholdServiceImpl.save(HouseholdServiceImpl.java:24)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
            at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
            at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
            at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
            at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
            at com.sun.proxy.$Proxy41.save(Unknown Source)
            at com.chrishammer.controller.CreateAccountController.submitUser(CreateAccountController.java:34)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
            at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
            at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
            at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
            at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
            at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
            at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
            at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
            at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
            at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
            at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
            at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
            at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
            at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:495)
            at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
            at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:767)
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1347)
            at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)

的persistence.xml

<persistence    xmlns="http:://java.sun.com/xml/ns.persistence"
            xmlns:xsi="http:://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http:://java.sun.com/xml/ns.persistence 
                                http:://java.sun.com/xml/ns/persistence_2_0.xsd"
            version ="2.0" >


<persistence-unit name="punit">
    <property name="javax.persistence.validation.mode" value="none"/>
</persistence-unit>             



</persistence>

jpaContext.xml

<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

<context:annotation-config />
<context:component-scan base-package="com.chrishammer" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />


<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="punit" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name ="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <entry key="hibernate.hbm2ddl.auto" value="update" />
            <entry key="hivernate.format_sql" value="true" />
        </map>
    </property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/testingDb?autoReconnect=true" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>
</beans>

如果您需要任何其他信息,请告知我们,我们非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。在查看发现here的hibernate bean验证文档时,我注意到persistence.xml文件中的<property>标记被<properties>标记包围。只需将其添加到我的persistence.xml文件即可解决我的问题。