简体   繁体   English

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

[英]trying to use HibernateTransactionManager, but transactional services throw HibernateException

I'm trying to convert a Spring 4 project to use HibernateTransactionManager to manage the transactions, but transactional services throw this exception: 我正在尝试将Spring 4项目转换为使用HibernateTransactionManager来管理事务,但是事务服务抛出此异常:

org.hibernate.HibernateException: createSQLQuery is not valid without active transaction org.hibernate.HibernateException:如果没有活动事务,createSQLQuery无效

I've searched on google, and 80 different people have 80 different ways of doing it. 我在Google上进行过搜索,有80个不同的人有80种不同的操作方式。 I've tried them all, and either they don't work or they require using EntityManager instead of Hibernate Sessions. 我已经尝试了所有这些,或者它们不起作用,或者它们需要使用EntityManager而不是Hibernate Sessions。 Since I'm converting existing code that uses Hibernate sessions, things would be far easier if I could get them to work. 由于我正在转换使用Hibernate会话的现有代码,因此如果可以使它们工作,事情会容易得多。 How do I get rid of this exception? 我如何摆脱这种例外?

  • Spring version: 4.2.5.RELEASE 春季版本:4.2.5.RELEASE
  • Hibernate version: 5.1.0.Final 休眠版本:5.1.0。最终
  • Hikari version: 2.7.6 光版:2.7.6
  • JDK version: 1.8.0_161 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);
        }
    }
}

Session factory config: 会话工厂配置:

@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);
        }
    }
}

Transaction config: 交易配置:

@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: 服务:

@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;
    }
}

Any ideas? 有任何想法吗? I hope so because I'm out. 我希望是因为我不在。

Buried in our settings was this innocent-looking one, in there since the initial git checkin of our project, so I cannot find out who put it in (they're lucky): 自从我们项目的最初git checkin以来,就在我们的设置中埋葬了这个看起来很天真的设置,所以我找不到谁把它放进去(他们很幸运):

hibernate.current_session_context_class = thread hibernate.current_session_context_class =线程

Since no one knew what this setting was for, no one dared touch it since then. 由于没有人知道此设置的用途,因此此后没有人敢尝试。 This breaks Spring managed transactions, and had no business being in there. 这中断了Spring管理的事务,并且那里没有业务。

Let's this be a lesson, boys and girls: if you're trying to get something to work, DON'T just fiddle with settings when you don't know what they are. 让我们这是一个教训,男孩和女孩:如果您想让某件事起作用,那么当您不知道设置是什么时,不要只是摆弄设置。 It will come back to bite you in the ass--sometimes years later. 有时几年后,它会再次咬住你。 And then I will come find you and get you. 然后我会找到你并得到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM