如果没有活动事务或无效状态,createQuery无效,连接对象将关闭

时间:2016-07-07 13:56:50

标签: spring hibernate spring-mvc

我有以下Java配置文件:

@Configuration
@ComponentScan(basePackages="com.blahblah")
@EnableWebMvc
@EnableTransactionManagement
@Import({ SecurityConfig.class })

public class MvcConfiguration extends WebMvcConfigurerAdapter{

    @Bean
    public ViewResolver getViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Bean
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
        dataSource.setUrl("jdbc:jtds:sqlserver://localhost:1433/VacationDB;instance=SQLEXPRESS");
        dataSource.setUsername("bavarezul13");
        dataSource.setPassword("Scholl1313.");

        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean  sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(getDataSource());
        sessionFactory.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));

        return sessionFactory;
     }

    @Bean(name = "transactionManager")
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
       HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory);
       return txManager;
    }

}    

我的DAO实现注释了@Transactional,我有一个这样的方法:

@Repository(value="VacationDAOImplHibernate")
@Transactional
public class VacationDAOImplHibernate implements VacationDAO{

    @Autowired
    SessionFactory sessionFactory;

    @Override
    public VacationHibernate getVacation(int id) {

        Session session = sessionFactory.getCurrentSession();
        //Transaction tx = session.beginTransaction();

        String hql = "from VacationHibernate v where v.id = :id";
        @SuppressWarnings("unchecked")
        List<VacationHibernate> listVacationHibernate = session.createQuery(hql).setParameter("id", id).list();
        VacationHibernate vh = listVacationHibernate.get(0);
        //tx.commit();
        session.close();

        return vh;
    }
}

如果我创建一个事务并提交它,一切正常。如果没有,我收到错误:java.sql.SQLException: Invalid state, the Connection object is closed如果我从hibernate.cfg.xml中删除以下行:<property name="current_session_context_class">thread</property>org.hibernate.HibernateException: createQuery is not valid without active transaction,并在hibenrate.cfg.xml中使用该行。

自己开始并提交交易不会有问题,但Transaction tx = session.beginTransaction();需要6秒!!!(我不知道为什么)

2 个答案:

答案 0 :(得分:0)

我找到了一个解决我的错误的方法:我在hibernate.cg.xml中删除了name="current_session_context_class">thread</property>,所以我遇到了错误:java.sql.SQLException: Invalid state, the Connection object is closed正如我在问题中所说的那样。 然后我删除了session.close();,错误就消失了。

现在一切正常,Spring正在管理交易,但也需要花费大量时间才能打开它。 我怀疑它可能是驱动程序的问题

<dependency>
          <groupId>net.sourceforge.jtds</groupId>
          <artifactId>jtds</artifactId>
          <version>1.3.1</version>
      </dependency>

答案 1 :(得分:0)

Marius,您也可以尝试在应用程序中设置连接池以改善数据库连接检索时间,例如我们使用DBCP2作为连接池,如下面给出的示例

@Bean
public DataSource dataSource() {

    final org.apache.commons.dbcp2.BasicDataSource dataSource = new org.apache.commons.dbcp2.BasicDataSource();
    dataSource.setDriverClassName("org.postgresql.Driver");
    dataSource.setUrl("jdbc:postgresql://localhost:5432/myproject-db");
    dataSource.setUsername("username");
    dataSource.setPassword("password");
    dataSource.setInitialSize(2 * 5);
    dataSource.setMaxTotal(2 * 50);
    dataSource.setLogAbandoned(true);
    dataSource.setMaxIdle(2);
    dataSource.setMaxConnLifetimeMillis(3 * 60 * 1000); // Milliseconds (3 minutes)
    dataSource.setPoolPreparedStatements(true);

    return dataSource;
}