hibernate 5 - 无法获取当前线程的事务同步会话;
hibernate 5 - Could not obtain transaction-synchronized Session for current thread;
如果我打开一个新会话,我可以使用会话,但是,如果我尝试获取我认为不存在的当前会话,我会收到此错误。
坚持-h2.properties
# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my-database
jdbc.eventGeneratedId=sa
jdbc.user=root
jdbc.pass=root_password
# hibernate.X
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=validate
# hibernate.search.X
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /data/index/default
# envers.X
envers.audit_table_suffix=_audit_log
HibernateConfig.java
package com.buraktas.spring;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
@ComponentScan({ "com.buraktas" })
public class HibernateConfig {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.buraktas.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
@Bean
public PlatformTransactionManager hibernateTransactionManager() {
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", "true");
// Envers properties
hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
return hibernateProperties;
}
}
PersonDaoImp.java
@Repository
public class PersonDaoImp implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
public Person getPerson(int id) {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.get(Person.class, 1);
}
}
在这里,如果我使用 sessionFactory.openSession()
,那么我就可以查询我的数据库。但我不想每次都创建一个新会话并关闭它。我以为我还需要添加 current_session_context_class
和 connection.pool_size
属性,但这并没有解决问题。长话短说,我如何初始化连接池或会话池?
谢谢!
这是一个迟到的回复,但正如我在评论中提到的那样,在 class 级别添加 @Transactional 是有效的。
如果我打开一个新会话,我可以使用会话,但是,如果我尝试获取我认为不存在的当前会话,我会收到此错误。
坚持-h2.properties
# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my-database
jdbc.eventGeneratedId=sa
jdbc.user=root
jdbc.pass=root_password
# hibernate.X
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=validate
# hibernate.search.X
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /data/index/default
# envers.X
envers.audit_table_suffix=_audit_log
HibernateConfig.java
package com.buraktas.spring;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-h2.properties" })
@ComponentScan({ "com.buraktas" })
public class HibernateConfig {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.buraktas.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
@Bean
public PlatformTransactionManager hibernateTransactionManager() {
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", "true");
// Envers properties
hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
return hibernateProperties;
}
}
PersonDaoImp.java
@Repository
public class PersonDaoImp implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
public Person getPerson(int id) {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.get(Person.class, 1);
}
}
在这里,如果我使用 sessionFactory.openSession()
,那么我就可以查询我的数据库。但我不想每次都创建一个新会话并关闭它。我以为我还需要添加 current_session_context_class
和 connection.pool_size
属性,但这并没有解决问题。长话短说,我如何初始化连接池或会话池?
谢谢!
这是一个迟到的回复,但正如我在评论中提到的那样,在 class 级别添加 @Transactional 是有效的。