spring mvc + hibernate:createSQLQuery 在没有活动事务的情况下无效
spring mvc + hibernate: createSQLQuery is not valid without active transaction
我的代码的旧版本:
Session session = sessionFactory.openSession();
Query query = session.createQuery("From User");
List<Users> users = query.list();
session.close();
我配置hibernate.cfg.xml文件:
<property name="hibernate.current_session_context_class" > thread</property >
context.xml
<tx:annotation-driven transaction-manager="transactionManager"/>
当前代码:
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("From User");
List<Users> list = query.list();
tx.commit();
我必须添加交易代码,否则我会得到一个错误
org.hibernate.HibernateException: createQuery is not valid without active transaction
我缺少什么配置?
ApplicationContext.xml
<?xml version='1.0' encoding='UTF-8' ?>
......
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<context:annotation-config />
<context:component-scan base-package="*" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
public class IndexController {
@Autowired
UserService users;
@RequestMapping("/index")
public String index(ModelMap model ) {
User user= users.test();
model.put("user", user);
return "index";
}
如果您不使用 JTA,只需删除此 属性。 Spring默认做管理事务。
并在 spring 配置中定义事务管理器:
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
按照@eg04lt3r 的建议,您不需要 hibernate.cfg.xml
中的这一行
<property name="hibernate.current_session_context_class">thread</property>
您需要正确配置 spring 上下文。
对于会话工厂,如果您在 hibernate.cfg.xml
和 hibernate.properties
中有映射和属性
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" />
用于事务管理
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
在与会话一起工作的class中
public class Service {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public List<User> list() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from User");
return (List<User>) query.list();
}
}
当然不能通过这种方式获取用户
new Service().list()
您需要从 spring 上下文中获取 Service
。 Spring 将在 Service
和 return 中设置 sessionFactory
Service
的代理。当您调用 list()
时,代理会打开一个会话并创建一个事务。
更新
我重现了你的问题。使用此 classes 一切正常
public interface TextService {
public void save();
public List<SingleText> test();
}
@Service
public class TextServiceImpl implements TextService {
@Autowired
private SessionFactory sessionFactory;
@Override
@Transactional
public void save() {
SingleText text = new SingleText();
text.setTestText("S.Grey");
Session session = sessionFactory.getCurrentSession();
session.save(text);
}
@Override
@Transactional
public List<SingleText> test() {
Session session = sessionFactory.getCurrentSession();
return session.createCriteria(SingleText.class).list();
}
}
没有 @Transactional
注释我得到了
org.hibernate.HibernateException: No Session found for current thread
或(取决于 Spring 版本)
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
所以你只需要 @Transaction
注释。你不需要这个
<property name="hibernate.current_session_context_class">thread</property>
我的代码的旧版本:
Session session = sessionFactory.openSession();
Query query = session.createQuery("From User");
List<Users> users = query.list();
session.close();
我配置hibernate.cfg.xml文件:
<property name="hibernate.current_session_context_class" > thread</property >
context.xml
<tx:annotation-driven transaction-manager="transactionManager"/>
当前代码:
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("From User");
List<Users> list = query.list();
tx.commit();
我必须添加交易代码,否则我会得到一个错误
org.hibernate.HibernateException: createQuery is not valid without active transaction
我缺少什么配置?
ApplicationContext.xml
<?xml version='1.0' encoding='UTF-8' ?>
......
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<context:annotation-config />
<context:component-scan base-package="*" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
public class IndexController {
@Autowired
UserService users;
@RequestMapping("/index")
public String index(ModelMap model ) {
User user= users.test();
model.put("user", user);
return "index";
}
如果您不使用 JTA,只需删除此 属性。 Spring默认做管理事务。
并在 spring 配置中定义事务管理器:
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
按照@eg04lt3r 的建议,您不需要 hibernate.cfg.xml
<property name="hibernate.current_session_context_class">thread</property>
您需要正确配置 spring 上下文。
对于会话工厂,如果您在 hibernate.cfg.xml
和 hibernate.properties
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" />
用于事务管理
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
在与会话一起工作的class中
public class Service {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public List<User> list() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from User");
return (List<User>) query.list();
}
}
当然不能通过这种方式获取用户
new Service().list()
您需要从 spring 上下文中获取 Service
。 Spring 将在 Service
和 return 中设置 sessionFactory
Service
的代理。当您调用 list()
时,代理会打开一个会话并创建一个事务。
更新
我重现了你的问题。使用此 classes 一切正常
public interface TextService {
public void save();
public List<SingleText> test();
}
@Service
public class TextServiceImpl implements TextService {
@Autowired
private SessionFactory sessionFactory;
@Override
@Transactional
public void save() {
SingleText text = new SingleText();
text.setTestText("S.Grey");
Session session = sessionFactory.getCurrentSession();
session.save(text);
}
@Override
@Transactional
public List<SingleText> test() {
Session session = sessionFactory.getCurrentSession();
return session.createCriteria(SingleText.class).list();
}
}
没有 @Transactional
注释我得到了
org.hibernate.HibernateException: No Session found for current thread
或(取决于 Spring 版本)
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
所以你只需要 @Transaction
注释。你不需要这个
<property name="hibernate.current_session_context_class">thread</property>