Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushM

简介:


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.


在使用hibernate模板对数据库进行读写操作时,有时会遇到删除、写入操作受限,对于这种异常,可以多种办法解决,

首先你测试先一下是添加受限,还是删除受限,如果添加和删除有一个可以成功,那么错误可能是:


第一)种错误,没有给对应方法配置权限,

<props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="do*">PROPAGATION_REQUIRED</prop>
    <prop key="recv*">PROPAGATION_REQUIRED</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
   </props>


第二)种错误,在Dao层中添加,删除方法错误,请测试查看异常


如果添加和删除都不成功,那么很有可能就是权限问题了,请继续看,以下办法可以解决

1)第一种在Dao层更改 session.setFlushMode(FlushMode.AUTO);

    操作如下:

//注入  hibernateTemplate
private HibernateTemplate hibernateTemplate;
//生成get(),set()方法
 public HibernateTemplate getHibernateTemplate()
 {
  return hibernateTemplate;
 }
 public void setHibernateTemplate(HibernateTemplate hibernateTemplate)
 {
  this.hibernateTemplate = hibernateTemplate;
 }
/**
  * 根据id删除记录
  * @param id
  */
 @Transactional("txManager")
 public int removeUser(Integer id)
 {
  // 1.参数检测
  if (index != null && hibernateTemplate != null&& hibernateTemplate.getSessionFactory() != null)
  {
   // 2.取得sission
   Session session = hibernateTemplate.getSessionFactory()
     .getCurrentSession();
   if (session != null)
   {
    //2.1 设置session属性
    session.setFlushMode(FlushMode.AUTO);
    // 2.2删除该id的对象
    Query query = session.createQuery("from User  where id ="
      + id);
    Comment comment = null;
    //3 非空检查
    if (query != null)
    {
     if (query.list().size() > 0)
     {
      user = (Comment) (query.list().get(0));
      // 4.1删除该对象
      hibernateTemplate.delete(user);
      // 4.2清理缓存
      session.flush();
     //返回一个表示,成功返回1,失败返回0
      return 1;
     }
    }
   }
  }
  return 0;
 }


2 ) 第二种在配置文件web.xml和applicationContext.xml中更改

web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>Doshare</display-name>
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
 <filter>
  <filter-name>OpenSessionInViewFilter</filter-name>
  <filter-class>
 org.springframework.orm.hibernate3.support.OpenSessionInViewFilter    
  </filter-class>
  <init-param>
   <param-name>sessionFactoryBeanName</param-name>
   <param-value>sessionFactory</param-value>
  </init-param>
  <init-param>
   <param-name>singleSession</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>flushMode</param-name>
   <param-value>AUTO </param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>OpenSessionInViewFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <jsp-config>
  <jsp-property-group>
   <display-name>JSPConfiguration</display-name>
   <url-pattern>*.htm</url-pattern>
   <el-ignored>true</el-ignored>
   <page-encoding>UTF-8</page-encoding>
   <scripting-invalid>false</scripting-invalid>
  </jsp-property-group>
  <jsp-property-group>
   <display-name>JSPConfiguration</display-name>
   <url-pattern>*.jsp</url-pattern>
   <el-ignored>false</el-ignored>
   <page-encoding>UTF-8</page-encoding>
   <scripting-invalid>false</scripting-invalid>
  </jsp-property-group>
 </jsp-config>
 <!-- Struts2 核心过滤器 -->
 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <!-- Spring 監聽器 -->
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app>


applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd">
 <!-- 指定C3P0连接池 -->
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
  destroy-method="close">
  <property name="driverClass" value="org.mariadb.jdbc.Driver"></property>
  <property name="jdbcUrl"
   value="jdbc:mysql://localhost:3308/test?userUnicode=true&characterEncoding=UTF-8"></property>
<!--数据库用户名和密码-->
  <property name="user" value="root"></property>
  <property name="password" value="123456"></property>
<!--最大连接数-->
  <property name="maxPoolSize" value="500"></property>
<!--最小连接数-->
  <property name="minPoolSize" value="5"></property>
  <!-- 保持MySQL连接 -->
  <property name="preferredTestQuery" value="SELECT 1"></property>
 </bean>
 <!-- 使用Spring管理Hibernate -->
 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"></property>
  <!-- Hibernate的属性 -->
  <property name="hibernateProperties">
   <props>
    <!-- 连接池自动重连 -->
    <prop key="hibernate.connection.autoReconnectForPools">true</prop>
    <!-- 连接编码 -->
    <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
    <!-- 方言 -->
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <!-- showsq -->
    <prop key="hibernate.show_sql">true</prop>
    <!-- 避免JDBC出错,仅限于MySQL -->
    <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
    <!-- 自动创建表 -->
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext
    </prop>
   </props>
  </property>
  <property name="mappingResources">
   <list>
     <value>com/doshr/xmen/app/server/bean/Comment.hbm.xml</value>
    <value>com/doshr/xmen/app/server/bean/WeChatFriend.hbm.xml</value>
    <value>com/doshr/xmen/app/server/bean/Address.hbm.xml</value>
    <value>com/doshr/xmen/app/server/bean/Propertyes.hbm.xml</value> 
   </list>
  </property>
 </bean>
 <!-- 配置Spring的Hibernate模板 -->
 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
 <!-- 配置Spring事务管理器 -->
 <bean id="txManager"
  class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
 <!-- 配置事務攔截器 -->
 <bean id="txInterceptor"
  class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <property name="transactionManager">
   <ref bean="txManager" />
  </property>
  <property name="transactionAttributes">
   <props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="do*">PROPAGATION_REQUIRED</prop>
    <prop key="recv*">PROPAGATION_REQUIRED</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="*">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
 </bean>
 <!-- 事务代理 -->
 <bean
  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
   <property name="interceptorNames">
   <list>
    <value>txInterceptor</value>
   </list>
  </property> 
   <property name="beanNames">
   <list>
    <value>*Dao</value>
    <value>*Service</value>
   </list>
  </property> 
 </bean>
</beans>


3)第三种写一个过滤器,让类(继承)extends
  org.springframework.orm.hibernate4.support.OpenSessionInViewFilter  重写方法

<!--结束-->

有问题的或者异常的,请说明信息,一起讨论


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
SQL 关系型数据库 MySQL
Mysql连接池详解——原理部分
Mysql连接池详解——原理部分
|
SQL 分布式计算 Hadoop
|
开发工具 git
git如何修改提交代码时的名字和邮箱?
git如何修改提交代码时的名字和邮箱?
7100 4
|
缓存 负载均衡 监控
探秘数据库中间件:ProxySQL与MaxScale的优势与劣势
探秘数据库中间件:ProxySQL与MaxScale的优势与劣势
1034 2
|
人工智能 自然语言处理 关系型数据库
阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成
近日,阿里云云原生数据仓库 AnalyticDB PostgreSQL 版已完成和开源LLMOps平台Dify官方集成。
|
Java API
Java时间戳教程
本文详细介绍Java中时间戳的处理方法,包括获取当前时间戳、使用`java.time`包、时间戳与日期的相互转换及格式化等。示例代码展示了如何利用`System.currentTimeMillis()`和`java.time.Instant`获取时间戳,以及如何通过`Date`和`ZonedDateTime`进行日期转换和时区处理。随着Java 8引入的`java.time`包,日期时间操作变得更加强大和便捷,推荐在新项目中优先采用。
1776 8
|
数据库 开发者 Java
颠覆传统开发:Hibernate与Spring Boot的集成,让你的开发效率飞跃式提升!
【8月更文挑战第31天】在 Java 开发中,Spring Boot 和 Hibernate 已成为许多开发者的首选技术栈。Spring Boot 简化了配置和部署过程,而 Hibernate 则是一个强大的 ORM 框架,用于管理数据库交互。将两者结合使用,可以极大提升开发效率并构建高性能的现代 Java 应用。本文将通过代码示例展示如何在 Spring Boot 项目中集成 Hibernate,并实现基本的数据库操作,包括添加依赖、配置数据源、创建实体类和仓库接口,以及在服务层和控制器中处理 HTTP 请求。这种组合不仅简化了配置,还提供了一套强大的工具来快速开发现代 Java 应用程序。
1238 1
|
数据采集 XML 数据挖掘
构建高效Python爬虫:探索BeautifulSoup与Requests库的协同工作
【7月更文挑战第31天】在数据驱动的世界里,掌握网络数据采集技术变得尤为重要。本文将深入探讨如何利用Python语言中的BeautifulSoup和Requests库来构建一个高效的网络爬虫。我们将通过实际案例,展示这两个库如何在爬取网页数据时相互配合,以及如何通过简单的编码实现数据的精准抓取。文章不仅提供代码示例,还讨论了在使用这些工具时应注意的一些常见陷阱和最佳实践。无论你是数据分析师、研究人员还是对爬虫技术感兴趣的程序员,这篇文章都将为你提供一个清晰的指导框架,帮助你快速入门并提高你的爬虫技能。
518 1
|
缓存 NoSQL Java
Spring基于注解整合Redis
【8月更文挑战第5天】
510 0
|
Web App开发 JSON 数据格式
谷歌浏览器json插件,Json-Handle插件下载安装使用
谷歌浏览器json插件,Json-Handle插件下载安装使用
5112 0