试图使用HibernateTransactionManager,但事务服务抛出HibernateException

时间:2018-03-02 23:28:11

标签: java spring hibernate spring-transactions

我正在尝试将Spring 4项目转换为使用HibernateTransactionManager来管理事务,但事务服务会抛出此异常:

  

org.hibernate.HibernateException:如果没有,createSQLQuery无效   活跃交易

我在google上搜索过,80个不同的人有80种不同的方法。我已经尝试了所有这些,要么它们不起作用,要么它们需要使用EntityManager而不是Hibernate Sessions。由于我正在转换使用Hibernate会话的现有代码,如果我能让它们工作,事情会容易得多。我该如何摆脱这种例外?

  • 春季版:4.2.5.RELEASE
  • Hibernate版本:5.1.0.Final
  • Hikari版本:2.7.6
  • JDK版本:1.8.0_161

DataSource config:

@Configuration
public class DataSourceConfig {
    @Bean
    public DataSource dataSource() {
        // return a Hikari connection pool as the data source
        try {
            HikariDataSource bean = new HikariDataSource();
            // set connection pool and JDBC properties
            return bean;
        } catch (Exception e) {
            throw new RuntimeException("could create data source", e);
        }
    }
}

会话工厂配置:

@Configuration
public class SessionFactoryConfig {
    @Autowired
    private DataSource dataSource;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        // create a session factory
        try {
            LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
            // set Hibernate properties
            bean.setDataSource(dataSource);
            bean.setPackagesToScan(packagesToScan);
            bean.setHibernateProperties(properties);
            bean.afterPropertiesSet(); // tried without this line as well
            return bean;
        } catch (Exception e) {
            throw new RuntimeException("could not create session factory", e);
        }
    }
}

交易配置:

@Configuration
@EnableTransactionManagement
@ComponentScan("com.mydomain.*")
public class TransactionConfig {
    @Autowired
    private SessionFactory sessionFactory;

    @Bean
    public PlatformTransactionManager transactionManager() {
        HibernateTransactionManager bean = new HibernateTransactionManager(sessionFactory);
//      bean.setHibernateManagedSession(true); // similar exception when set
        bean.afterPropertiesSet(); // tried without this line as well
        return bean;
    }
}

服务:

@Service
@Transactional // tried using only the @Transactional on the method
public class TestTransactionService {
    @Autowired
    private SessionFactory sessionFactory;

    @Transactional // tried using only the @Transactional on the class
    public String get(String key) {
        Session session = sessionFactory.getCurrentSession();
        // the below line throws the exception!
        SQLQuery q = session.createSQLQuery("SELECT value FROM test_transaction WHERE key = :key");
        q.setParameter("key", key);
        q.addScalar("value", StringType.INSTANCE);
        String out = (String)q.uniqueResult();
        return out;
    }
}

有什么想法吗?我希望如此,因为我出去了。

1 个答案:

答案 0 :(得分:0)

在我们的环境中埋葬了这个看起来无辜的人,自从我们项目的最初git签到以来,所以我找不到谁把它放进去(他们很幸运):

  

hibernate.current_session_context_class = thread

由于没有人知道这个设置是什么,从那以后没人敢碰它。这打破了Spring管理的交易,并且没有业务存在。

让我们这是一个教训,男孩和女孩:如果你想要一些工作,当你不知道它们是什么时,不要只是摆弄设置。它会回来咬你的屁股 - 有时几年后。然后我会来找你并找到你。