Hibernate 4 Spring 4 无法为当前线程获取事务同步会话
Hibernate 4 Spring 4 Could not obtain transaction-synchronized Session for current thread
@Repository
public class Init {
public static void main(String[] args) {
Init init = new Init();
init.addUser(init.getSessionFactory());
}
private SessionFactory getSessionFactory() {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
SessionFactory sf = (SessionFactory) context.getBean("sessionFactory");
return sf;
}
@Transactional
private void addUser(SessionFactory sf) {
Session session = sf.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
session.close();
sf.close();
}
}
xml:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.warmmer.bean" />
<property name="hibernateProperties">
<!-- <value> hibernate.dialect=org.hibernate.dialect.HSQLDialect </value> -->
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
错误:
信息:将 Hibernate SessionFactory 的 DataSource [org.apache.commons.dbcp.BasicDataSource@6098b14d] 用于 HibernateTransactionManager
线程 "main" org.hibernate.HibernateException 中的异常:无法为当前线程
获取事务同步会话
如果:
hibernate.current_session_context_class 设置 'thread'
然后 :save 在没有活动事务的情况下无效
请问我该怎么办?
您没有在 spring 上下文中创建 "Init" 对象,因此 spring 永远不会有机会使用将管理交易
尝试将您的 class 更改为...
package my.pkg;
// Imports etc
@Repository
public class Init {
@Autowired
private SessionFactory sessionFactory;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
Init init = context.getBean(Init.class);
init.addUser();
}
@Transactional
private void addUser() {
Session session = sessionFactory.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
// session.close(); DON'T NEED THESE!
// sf.close();
}
}
现在您可能需要将以下内容添加到您的 beans 文件中,以便它找到您的存储库...
<context:component-scan base-package="my.pkg"/>
@Repository
public class Init {
public static void main(String[] args) {
Init init = new Init();
init.addUser(init.getSessionFactory());
}
private SessionFactory getSessionFactory() {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
SessionFactory sf = (SessionFactory) context.getBean("sessionFactory");
return sf;
}
@Transactional
private void addUser(SessionFactory sf) {
Session session = sf.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
session.close();
sf.close();
}
}
xml:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.warmmer.bean" />
<property name="hibernateProperties">
<!-- <value> hibernate.dialect=org.hibernate.dialect.HSQLDialect </value> -->
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
错误: 信息:将 Hibernate SessionFactory 的 DataSource [org.apache.commons.dbcp.BasicDataSource@6098b14d] 用于 HibernateTransactionManager 线程 "main" org.hibernate.HibernateException 中的异常:无法为当前线程
获取事务同步会话如果: hibernate.current_session_context_class 设置 'thread'
然后 :save 在没有活动事务的情况下无效
请问我该怎么办?
您没有在 spring 上下文中创建 "Init" 对象,因此 spring 永远不会有机会使用将管理交易
尝试将您的 class 更改为...
package my.pkg;
// Imports etc
@Repository
public class Init {
@Autowired
private SessionFactory sessionFactory;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
Init init = context.getBean(Init.class);
init.addUser();
}
@Transactional
private void addUser() {
Session session = sessionFactory.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
// session.close(); DON'T NEED THESE!
// sf.close();
}
}
现在您可能需要将以下内容添加到您的 beans 文件中,以便它找到您的存储库...
<context:component-scan base-package="my.pkg"/>