我正在尝试将Spring 4项目转换为使用HibernateTransactionManager来管理事务,但事务服务会抛出此异常:
org.hibernate.HibernateException:如果没有,createSQLQuery无效 活跃交易
我在google上搜索过,80个不同的人有80种不同的方法。我已经尝试了所有这些,要么它们不起作用,要么它们需要使用EntityManager而不是Hibernate Sessions。由于我正在转换使用Hibernate会话的现有代码,如果我能让它们工作,事情会容易得多。我该如何摆脱这种例外?
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;
}
}
有什么想法吗?我希望如此,因为我出去了。
答案 0 :(得分:0)
在我们的环境中埋葬了这个看起来无辜的人,自从我们项目的最初git签到以来,所以我找不到谁把它放进去(他们很幸运):
hibernate.current_session_context_class = thread
由于没有人知道这个设置是什么,从那以后没人敢碰它。这打破了Spring管理的交易,并且没有业务存在。
让我们这是一个教训,男孩和女孩:如果你想要一些工作,当你不知道它们是什么时,不要只是摆弄设置。它会回来咬你的屁股 - 有时几年后。然后我会来找你并找到你。