2015-01-13 66 views
1

我的嘗試運行使用Spring 4簡單的應用程序,休眠4,和c3p0池,我不斷收到此錯誤:彈簧4 + hibernate的4個+ C3P0:無法獲得交易同步會話當前線程的

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Invocation of init method failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1560) 
    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.preInstantiateSingletons(DefaultListableBeanFactory.java:762) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:724) 
Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) 
    at ggdb.components.database.dao.GenericDao.getCurrentSession(GenericDao.java:61) 
    at ggdb.components.database.dao.UserDao.getUser(UserDao.java:36) 
    at ggdb.components.database.dao.UserDao.postConstruct(UserDao.java:24) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349) 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300) 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133) 
    ... 23 more 

這裏是我的配置:

@Configuration 
@EnableTransactionManagement 
@PropertySource("classpath:application.properties") 
public class DatabaseConfigutarion implements TransactionManagementConfigurer { 

    @Autowired 
    private Environment env; 

    public class PropertiesKeys { 

     public static final String DATABASE_HOST = "database.host"; 
     public static final String DATABASE_PORT = "database.port"; 
     public static final String DATABASE_USERNAME = "database.username"; 
     public static final String DATABASE_PASSWORD = "database.password"; 
     public static final String DATABASE_NAME = "database.database_name"; 
     public static final String DATABASE_ADDITIONAL_CONNECTION_PROPERTIES = "database.additional.connection.properties"; 

     public static final String HIBERNATE_DEFAULT_SCHEMA = "hibernate.default_schema"; 
     public static final String HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto"; 

    } 

    @Bean 
    public SessionFactory sessionFactory() { 
     String databaseUrl = String.format("jdbc:mysql://%s:%s/%s", env.getProperty(PropertiesKeys.DATABASE_HOST), env.getProperty(PropertiesKeys.DATABASE_PORT), env.getProperty(PropertiesKeys.DATABASE_NAME)); 
     String additionnalProperties = env.getProperty(PropertiesKeys.DATABASE_ADDITIONAL_CONNECTION_PROPERTIES); 
     databaseUrl = (additionnalProperties.isEmpty() ? databaseUrl : String.format("%s?%s", databaseUrl, additionnalProperties)); 

     org.hibernate.cfg.Configuration configuration = new org.hibernate.cfg.Configuration(); 
     configuration.setProperty("hibernate.connection.driver_class", com.mysql.jdbc.Driver.class.getName()); 
     configuration.setProperty("hibernate.connection.url", databaseUrl); 
     configuration.setProperty("hibernate.connection.username", env.getProperty(PropertiesKeys.DATABASE_USERNAME)); 
     configuration.setProperty("hibernate.connection.password", env.getProperty(PropertiesKeys.DATABASE_PASSWORD)); 

     configuration.setProperty("hibernate.c3p0.min_size", "5"); 
     configuration.setProperty("hibernate.c3p0.max_size", "20"); 
     configuration.setProperty("hibernate.c3p0.timeout", "1800"); 
     configuration.setProperty("hibernate.c3p0.max_statements", "50"); 

     configuration.setProperty("hibernate.current_session_context_class", org.springframework.orm.hibernate4.SpringSessionContext.class.getName()); 
     configuration.setProperty("hibernate.dialect", org.hibernate.dialect.MySQL5InnoDBDialect.class.getName()); 
     configuration.setProperty("hibernate.show_sql", "false"); 
     configuration.setProperty("hibernate.format_sql", "false"); 
     configuration.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false"); 
     configuration.setProperty("hibernate.default_schema", env.getProperty(PropertiesKeys.HIBERNATE_DEFAULT_SCHEMA)); 
     configuration.setProperty("hibernate.hbm2ddl.auto", env.getProperty(PropertiesKeys.HIBERNATE_HBM2DDL_AUTO)); 

     configuration.addAnnotatedClass(ggdb.components.database.entities.User.class); 
     configuration.addAnnotatedClass(ggdb.components.database.entities.Role.class); 

     ServiceRegistry serviceRegistry = (new StandardServiceRegistryBuilder()) 
       .applySettings(configuration.getProperties()) 
       .build(); 

     SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
     return sessionFactory; 
    } 

    @Bean 
    public HibernateTransactionManager transactionManager(){ 
     HibernateTransactionManager transactionManager = new HibernateTransactionManager(); 
     transactionManager.setSessionFactory(sessionFactory()); 
     return transactionManager; 
    } 

    @Override 
    public HibernateTransactionManager annotationDrivenTransactionManager() { 
     return transactionManager(); 
    } 

    public Environment getEnv() { 
     return env; 
    } 

    public void setEnv(Environment env) { 
     this.env = env; 
    } 

} 

和代碼拋出錯誤:

@Repository 
public class UserDao extends GenericDao<User> { 

    public UserDao() { 
     super(User.class); 
    } 

    // TODO: this method is temporary, 
    // should be removed later, 
    @PostConstruct 
    @Transactional 
    public void postConstruct() { 
     User user = getUser("user"); 
     if (user == null) { 
      user = new User(); 
      user.setUsername("user"); 
      user.setPassword("pass"); 
      save(user); 
     } 
    } 

    @Transactional 
    public User getUser(String username) { 
     @SuppressWarnings("unchecked") 
     List<User> users = (List<User>) getCurrentSession().getNamedQuery(User.FIND_BY_USERNAME).setParameter("username", username).list(); 
     return (users.isEmpty() ? null : users.get(0)); 
    } 

} 

Ë xtended class code:

public class GenericDao<T> { 

    private final Class<T> parameterClass; 

    @Autowired 
    protected SessionFactory sessionFactory; 

    public GenericDao(Class<T> parameterClass) { 
     this.parameterClass = parameterClass; 
    } 

    protected Session getSession() { 
     return sessionFactory.getCurrentSession(); 
    } 

    public Long save(T t) { 
     return (Long) getSession().save(t); 
    } 

    public void delete(Long id) { 
     getSession().delete(id); 
    } 

    @SuppressWarnings("unchecked") 
    public T get(Long id) { 
     return (T) getSession().get(parameterClass, id); 
    } 

    public void refresh(T t) { 
     getSession().refresh(t); 
    } 

    @SuppressWarnings("unchecked") 
    public T merge(T t) { 
     return (T) getSession().merge(t); 
    } 

    public void update(T t) { 
     getSession().update(t); 
    } 

    public void saveOrUpdate(T t) { 
     getSession().saveOrUpdate(t); 
    } 

    public SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public Session getCurrentSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
} 

你能幫助我嗎?哪裏有問題?

+2

'@ PostConstruct'沒有給出所有東西都已經安裝完畢,通常你沒有事務設置。 –

+0

手動事務管理很流行2003,請看'@ Transactional'註釋。 – Tobb

+0

Tobb,如果您有任何可以改進我的代碼的地方,請告訴我更簡單一點,因爲我沒有明白您的意思。 – M314

回答

0

調用init方法失敗。您可以嘗試添加:

@Autowired 
public void init(SessionFactory factory) { 
    setSessionFactory(factory); 
} 

到您的GenericDAO。

相關問題