简体   繁体   English

Spring MVC + Hibernate:没有活动事务,createSQLQuery无效

[英]spring mvc + hibernate: createSQLQuery is not valid without active transaction

The old version of my code: 我的代码的旧版本:

    Session session = sessionFactory.openSession();
    Query query = session.createQuery("From User");
    List<Users> users = query.list();
    session.close();

I config the hibernate.cfg.xml file: 我配置了hibernate.cfg.xml文件:

<property name="hibernate.current_session_context_class" > thread</property > <property name =“ hibernate.current_session_context_class”>线程</ property>

context.xml context.xml

<tx:annotation-driven transaction-manager="transactionManager"/> <tx:annotation驱动的transaction-manager =“ transactionManager” />

Current code: 当前代码:

  Session session = sessionFactory.getCurrentSession();
  Transaction tx = session.beginTransaction();
  Query query = session.createQuery("From User");
  List<Users> list = query.list();
  tx.commit();

I have to add Transaction code, or I will get an error 我必须添加交易代码,否则会出现错误

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

What am I missing for the config? 我缺少什么配置?

ApplicationContext.xml 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";
}

As suggested @eg04lt3r you don't need this line in the hibernate.cfg.xml 如建议的@ eg04lt3r,您不需要在hibernate.cfg.xml这一行

<property name="hibernate.current_session_context_class">thread</property>

You need to configure your spring context properly. 您需要正确配置spring上下文。

For the session factory, if you have mapping and properties in hibernate.cfg.xml and hibernate.properties 对于会话工厂,如果在hibernate.cfg.xmlhibernate.properties具有映射和属性

<bean id="sessionFactory"  
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" />

for a transaction management 用于交易管理

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager"   
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

In a class that works with a session 在适用于会话的课程中

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

}

You can't get users by this way of course 当然,您无法通过这种方式吸引用户

new Service().list()

You need to get Service from the spring context. 您需要从spring上下文获得Service Spring will set sessionFactory in the Service and return a proxy for Service . Spring将设置sessionFactoryService ,并返回一个代理Service When you call list() a proxy open a session and create a transaction. 当您调用list() ,代理打开会话并创建事务。

Update 更新资料

I reproduce your problem. 我重现您的问题。 With this classes everything works fine 通过此类,一切正常

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

}

Without the @Transactional annotation I got 没有@Transactional注释,我得到了

org.hibernate.HibernateException: No Session found for current thread

or (it depends of the Spring version) 或(取决于Spring版本)

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

So you just need the @Transaction annotation. 因此,您只需要@Transaction批注。 And you don't need this 而且你不需要这个

<property name="hibernate.current_session_context_class">thread</property> 

Just remove this property if you do not use JTA. 如果不使用JTA,只需删除此属性。 Spring do management transaction by default. Spring默认执行管理事务。

And define transaction manager in spring configuration: 并在spring配置中定义事务管理器:

<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name = "sessionFactory" ref = "sessionFactory" />
</bean>

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

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