Spring整合Hibernate遇到的问题

1、刷新模式的问题,FlushMode.MANUAL

Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
    org.springframework.orm.hibernate5.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1165)
    org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:643)
    org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:640)
    org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:359)
    org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:326)
    org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:640)

这里主要的是因为使用的是getCurrentSession获取的Session对象,在整合到Srping中的时候会遇到。FlushMode.MANUAL只读,所以进行增删改的时候就会抛出该异常。
解决方案:亲测靠谱
OpenSessionInViewFilter这个过滤器的源码:
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
try {
Session session = sessionFactory.openSession();
session.setFlushMode(FlushMode.MANUAL);
return session;
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException(“Could not open Hibernate Session”, ex);
}
}
就是会将Session的刷新模式设置,这样就导致了新增、修改、删除时无法操作。
我们只需要重写该过滤器的openSession方法覆盖原来的方法即可

SetSessionFlushModel类

public class SetSessionFlushModel extends OpenSessionInViewFilter{

    //覆盖父类中创建Session的方式,因为父类总创建Session,默认设置Session的setFlushMode为FlushMode.MANUAL就是只读模式
    @Override
    protected Session openSession(SessionFactory factory) throws DataAccessResourceFailureException {
        // TODO Auto-generated method stub
        Session session=factory.openSession();
        session.setFlushMode(FlushModeType.AUTO);//设置刷新模式也就是什么时候将sql语句发送到数据库

        return session;
    }

}

然后在web.xml中进行过滤器的注册
再次运行我们的整合项目就可以了。
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>My_SH</display-name>
  <!--开启Spring的监听器  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--配置Spring的配置文件  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--配置过滤器,解决session的flushMode的问题  -->
  <filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.qf.web.filter.SetSessionFlushModel</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

2、事物未开启

getHibernateFlushMode is not valid without active transaction; nested exception is org.hibernate.HibernateException: getHibernateFlushMode is not valid without active transaction
rg.springframework.orm.hibernate5.HibernateSystemException: getHibernateFlushMode is not valid without active transaction; nested exception is org.hibernate.HibernateException: getHibernateFlushMode is not valid without active transaction
    org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:296)
    org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:362)
    org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:326)
    org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:640)

明明配置了事物,而且aop切面也没有什么问题,可是就是出现这种问题。原来罪魁祸首是

<prop key="hibernate.current_session_context_class">thread</prop>

这个搞的鬼,在Hibernate的确是这样配置的,目的是使用getCurrentSession.
可是在整合的时候,必须使用这个:

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>

这样就好了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值