Sunday, June 2, 2013

I was stun when Hibernate validation throwing indexOutOfBoundsException.

    <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory">       
       <property name="dataSource">
           ...
       </property>

       <property name="hibernateProperties">
           ...
       </property>

       <property name="mappingResources">
           ...
       </property>
    </bean>

    <bean class="org.huahsin.dao.impl.TheDaoImpl" id="theDao">
       <property name="sessionFactory" ref="sessionFactory">
    </bean>
Take a look at the above code, when I load it up in the Liberty Profile server, an error complaining that sessionFactory was failed to initialize. Before this was working fine, not sure why this error suddenly shows up? Below are the stack trace for this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [spring/hibernate-spring.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to get the default Bean Validation factory
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1422)
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:518)
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
     at org.huahsin.test.CertificateSearchActionTest.<init>(CertificateSearchActionTest.java:24)
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
     at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.createTestInstance(PowerMockJUnit44RunnerDelegateImpl.java:188)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.createTest(PowerMockJUnit44RunnerDelegateImpl.java:173)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:195)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
     at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
     at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
     at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
     at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
     at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
     at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.hibernate.HibernateException: Unable to get the default Bean Validation factory
     at org.hibernate.cfg.beanvalidation.BeanValidationActivator.applyDDL(BeanValidationActivator.java:127)
     at org.hibernate.cfg.Configuration.applyBeanValidationConstraintsOnDDL(Configuration.java:1704)
     at org.hibernate.cfg.Configuration.applyConstraintsToDDL(Configuration.java:1654)
     at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1445)
     at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
     at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:717)
     at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1479)
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1419)
     ... 33 more
    Caused by: java.lang.reflect.InvocationTargetException
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     at java.lang.reflect.Method.invoke(Method.java:597)
     at org.hibernate.cfg.beanvalidation.BeanValidationActivator.applyDDL(BeanValidationActivator.java:118)
     ... 41 more
    Caused by: org.hibernate.HibernateException: Unable to build the default ValidatorFactory
     at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:383)
     at org.hibernate.cfg.beanvalidation.TypeSafeActivator.applyDDL(TypeSafeActivator.java:109)
     ... 46 more
    Caused by: javax.validation.ValidationException: Could not create Configuration.
     at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:175)
     at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:50)
     at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:380)
     ... 47 more
    Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
     at java.util.ArrayList.RangeCheck(ArrayList.java:547)
     at java.util.ArrayList.get(ArrayList.java:322)
     at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:173)
     ... 49 more
Searching on the stackoverflow.com I got this post by someone which also having the same problem similar to mine, but not exactly. He wrote:
3.6.0.Final seems to automatically turn on bean validation when an object is saved/updated through Hibernate. This is very bad because some of my tests don't bother setting all the properties - they just aren't needed.
This giving me a hints that it only happened in Hibernate 3.6.0 which is the same version as mine. In the mean time I got another post mention this:
By default Hibernate validator is set to auto, meaning if there is a validator in the classpath it will try to use it. GWT 2.3 and newer versions include the validation api inside the gwt-servlet.jar, so Hibernate ends up with a parcial validator and fails. If you don't want to use Hibernate Validation just turn it off in your properties (hibernate.cfg.xml, hibernate.properties or programatically).
Well, without thinking further, lets give it a try to turn off the Hibernate Validator, it might solve the problem. Putting this code into the hibernate configuration property:
    <property name="hibernateProperties">
       <props>
           ...
           <prop key="javax.persistence.validation.mode">none</prop>
       </props>
    </property>

No comments: