title: Using joda time with JPA/hibernate and spring
body: <p>I would to persist to db creation date and time. I have some experience with date and time classes but I dont like them. </p>
  
  <p>Recently I've started to use Joda time. I have to say that library is the best to work with date and time.</p>
  
  <p>For now I would like to persist DateTime object from joda.</p>
  
  <p>I've tried already:</p>
  
  <pre><code>@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
  private DateTime creationDate;
  </code></pre>
  
  <p>But it unfortunatelly dosnt work. Here is stack trace:</p>
  
  <pre><code>Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class com.derp.common.init.WebAppConfig: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
      ... 41 more
  Caused by: org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
      at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:510)
      at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:42)
      at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1472)
      at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1420)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:453)
      at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:438)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
      ... 51 more
  Caused by: org.hibernate.annotations.common.reflection.ClassLoadingException: Unable to load Class [org.joda.time.contrib.hibernate.PersistentDateTime]
      at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:60)
      at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:491)
      ... 61 more
  Caused by: java.lang.ClassNotFoundException: org.joda.time.contrib.hibernate.PersistentDateTime
      at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1324)
      at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1177)
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Class.java:344)
      at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57)
      ... 62 more
  </code></pre>
  
  <p>And my fragment of pom.xml:</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;joda-time&lt;/groupId&gt;
      &lt;artifactId&gt;joda-time&lt;/artifactId&gt;
      &lt;version&gt;2.5&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>I hope some one will help me.</p>
  
  <p>----Edited------</p>
  
  <p>WebMvcConfigurerAdapter</p>
  
  <pre><code>package com.derp.common.init;
  
  import java.util.Properties;
  
  import javax.annotation.Resource;
  import javax.sql.DataSource;
  
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.ComponentScan;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.PropertySource;
  import org.springframework.core.env.Environment;
  import org.springframework.http.MediaType;
  import org.springframework.jdbc.datasource.DriverManagerDataSource;
  import org.springframework.orm.hibernate4.HibernateTransactionManager;
  import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
  import org.springframework.transaction.annotation.EnableTransactionManagement;
  import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
  import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  
  //import com.derp.common.wicketView.HomePage;
  
  @Configuration
  @ComponentScan("com.derp")
  @EnableWebMvc
  @EnableTransactionManagement
  @PropertySource("classpath:application.properties")
  public class WebAppConfig extends WebMvcConfigurerAdapter {
  
      private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
      private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
      private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
      private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
  
      private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
      private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
      private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan";
      private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan";
  
      @Resource
      private Environment env;
  
      @Bean
      public DataSource dataSource() {
          DriverManagerDataSource dataSource = new DriverManagerDataSource();
          dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
          dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
          dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
          dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
          return dataSource;
      }
  
      @Bean
      public LocalSessionFactoryBean sessionFactory() {
          LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
          sessionFactoryBean.setDataSource(dataSource());
          //sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
          sessionFactoryBean.setPackagesToScan(new String[] {
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES),
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON),
                  env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS)
                  });
          sessionFactoryBean.setHibernateProperties(hibProperties());
          return sessionFactoryBean;
      }
  
      private Properties hibProperties() {
          Properties properties = new Properties();
          properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
          properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
          properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
          return properties;  
      }
  
      @Bean
      public HibernateTransactionManager transactionManager() {
          HibernateTransactionManager transactionManager = new HibernateTransactionManager();
          transactionManager.setSessionFactory(sessionFactory().getObject());
          return transactionManager;
      }
  
  
      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
          // Simple strategy: only path extension is taken into account
          configurer.favorPathExtension(true).
              ignoreAcceptHeader(true).
              useJaf(false).
              defaultContentType(MediaType.TEXT_HTML).
              mediaType("html", MediaType.TEXT_HTML).
              mediaType("xml", MediaType.APPLICATION_XML).
              mediaType("json", MediaType.APPLICATION_JSON);
      }
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*");
          registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*");
          registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*");
          registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*");
      }
  }
  </code></pre>
  
  <p>WebApplicationInitializer class:</p>
  
  <pre><code>package com.derp.common.init;
  
  import javax.servlet.ServletContext;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRegistration.Dynamic;
  
  import org.springframework.web.WebApplicationInitializer;
  import org.springframework.web.context.ContextLoaderListener;
  import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  import org.springframework.web.filter.HiddenHttpMethodFilter;
  import org.springframework.web.servlet.DispatcherServlet;
  
  public class Initializer implements WebApplicationInitializer {
  
  
      @Override
      public void onStartup(ServletContext servletContext) throws ServletException {
          AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
          ctx.register(WebAppConfig.class);
          ctx.register(ThymeleafConfig.class);
          servletContext.addListener(new ContextLoaderListener(ctx));
  
          ctx.setServletContext(servletContext);
  
          Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
          servlet.addMapping("/");
          servlet.setAsyncSupported(true);     
          servlet.setLoadOnStartup(1);
          // Allow to use Put and Delete method for REST architecture
          registerHiddenFieldFilter(servletContext);
      }
  
      private void registerHiddenFieldFilter(ServletContext aContext) {
          aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*"); 
      }
  }
  </code></pre>