2014-12-01 74 views
11

我会坚持创建db的日期和时间。我有日期和时间课的一些经验,但我不喜欢他们。在JPA/hibernate和spring中使用joda时间

最近我开始使用乔达时间。我不得不说图书馆是最好的与日期和时间。

现在我想坚持来自joda的DateTime对象。

我试过不已:

@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") 
private DateTime creationDate; 

但可惜的dosnt工作。下面是堆栈跟踪:

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 

我的pom.xml中的片段:

<dependency> 
    <groupId>joda-time</groupId> 
    <artifactId>joda-time</artifactId> 
    <version>2.5</version> 
</dependency> 

我希望有人能帮助我。

---- ------编辑

WebMvcConfigurerAdapter

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/*"); 
    } 
} 

WebApplicationInitializer类:

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, "/*"); 
    } 
} 
+0

根据这个问题,你可以添加它作为jpa属性:http://stackoverflow.com/questions/21130538/joda-time-and-hibernate-4 – bradleyfitz 2014-12-01 19:05:14

+0

你指出我的方法:'HibernateJpaVendorAdapter' dosnt存在于我的项目中,所以我不知道应该在哪里添加它。我已经使用WebAppConfig和启动器java conf类更新了我的帖子。你能看看这个吗? – masterdany88 2014-12-01 19:12:44

回答

13

您可以使用Jadira用于此目的:

添加这个给你的pom.xml:

<dependency> 
    <groupId>org.jadira.usertype</groupId> 
    <artifactId>usertype.extended</artifactId> 
    <version>3.2.0.GA</version> 
</dependency> 

和(在你的配置类hibProperties方法)把这个在您的休眠特性:

properties.put("jadira.usertype.autoRegisterUserTypes", "true"); 

完成这一步之后,你可以从你的乔达属性中删除@Type注解,它应该只是罚款(作品对于我来说Joda和JSR-310)。

+0

我按照你的指示,现在我已经在db列类型'TIMESTAMP(23,10)'让我们尝试把一些数据:D – masterdany88 2014-12-01 19:46:25

+0

你使用什么数据库?我正在使用postgres,这正确地为我生成'TIMESTAMP WITHOUT TIME ZONE'。 – 2014-12-01 20:01:55

+0

我使用h2db http://www.h2database.com/html/main.html – masterdany88 2014-12-01 20:26:35