2015-01-13 6 views
1

Я пытаюсь запустить простое приложение, которое использует Spring 4, Hibernate 4 и C3P0 пулов, и я получаю эту ошибку:Spring 4 + зимует 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)); 
    } 

} 

E 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

Ручное управление транзакциями - soo 2003, пожалуйста, посмотрите аннотацию '@ Transactional'. – Tobb

+0

Tobb, если у вас есть какие-либо моменты, где я могу улучшить свой код, пожалуйста, скажите мне немного более прямолинейно, потому что я не понимаю вашу точку зрения. – M314

ответ

0

Вызов метода init не удался. Вы можете попробовать:

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

к вашему GenericDAO.

Смежные вопросы

 Смежные вопросы