hibernate异常:Write operations are not allowed in read-only mode

hibernate异常:

解决Hibernate的Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition.


方法一:在出现异常的方法中加入:

getHibernateTemplate().setFlushMode(HibernateTemplate.FLUSH_EAGER);



方法二:重写OpenSessionInViewFilter:

package cn.com.farben.framework.util;
 
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
 
public class OpenSessionInViewFilter extends
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter {
    protected Session getSession(SessionFactory sessionFactory)
            throws DataAccessResourceFailureException {
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        session.setFlushMode(FlushMode.COMMIT);
        return session;
    }
 
    protected void closeSession(Session session, SessionFactory factory) {
        session.flush();
        super.closeSession(session, factory);
    }
}

web.xml


<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>cn.com.farben.framework.util.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>  
    <filter-name>hibernateFilter</filter-name>   
    <url-pattern>/*</url-pattern>  
</filter-mapping>


问题只读模式下(FlushMode.NEVER/MANUAL)写操作不被允许:把你的Session改成FlushMode.COMMIT/AUTO或者清除事务定义中的readOnly标记。

 

错误原因:
          OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction(声明式的事务)保护的方法有写权限,没受保护的则没有。








                
<think>好的,用户再次遇到了YAML文件的问题,具体错误是“yaml: line 13: mapping values are not allowed in this context”。我之前已经帮他修正过一个Docker Compose文件中的多个错误,现在需要分析这个新的错误。 首先,我需要确定这个错误的原因。YAML中的“mapping values are not allowed in this context”通常表示在某个地方,格式不正确,可能是缩进错误,或者冒号使用不当,或者键值对的位置不对。 用户之前提交的YAML文件有重复的volumes键,缩进错误,以及命令参数的问题。现在用户可能在新修改后的文件中又出现了类似的错误,或者可能是在其他位置出现了问题。 用户这次可能是在自己修改YAML的时候遇到了问题,比如可能在某个键下错误地使用了冒号,或者缩进层级不对。比如,在YAML中,每个键后面的值需要用正确的缩进,如果缩进不正确,或者在没有应该使用列表或标量的地方使用了映射,就会这个错误。 比如,假设在第13行,用户可能在一个应该使用列表的地方错误地使用了键值对,或者在键后面没有正确缩进。例如: environment: KEY: value ANOTHER_KEY: another_value SUB_KEY: sub_value # 这里缩进错误,导致解析错误 或者在某个键的值部分错误地使用了冒号而没有正确引用: command: --init-file: /path/to/file # 这里可能应该用空格而不是冒号,或者需要正确结构 另外,可能用户在某些地方遗漏了冒号后的空格,或者键名重复,或者使用了不正确的结构,比如在列表项中使用了键值对而没有正确缩进。 需要用户提供具体的第13行的内容才能准确判断,但根据之前的经验,用户可能在修正后的文件中某个服务下的某个键(如volumes、environment)的缩进不正确,或者在command或entrypoint的参数结构上有问题。 比如,在之前的修正中,合并了db服务的volumes,现在可能在新的行号下,用户又出现了类似的缩进错误,或者某个键的值部分使用了错误的语法结构。 可能的例子是,在command参数中,用户可能错误地拆分了参数,或者volumes的路径书写有误,导致YAML解析器认为这是一个映射而非列表项。 比如,原修正后的command部分: command: - "--init-file=/docker-entrypoint-initdb.d/init.sql" 如果用户在修改时不小心添加了额外的冒号或缩进,可能导致解析错误。或者,在某个环境变量的值中使用了未转义的冒号,而没有加引号,导致解析错误。 此外,用户可能在某个地方重复了键名,比如在services下的某个服务里,两次定义了volumes或environment,导致YAML解析器认为这是重复的键,从而错。 总结可能的错误点:缩进错误、冒号后缺少空格、键名重复、列表项结构不正确、未正确使用引号包裹含有特殊字符的值。 由于用户没有提供具体的第13行内容,我需要根据常见情况给出建议,并指导用户如何自行检查。同时,提醒用户使用docker compose config命令验证YAML文件的语法正确性,以及检查缩进是否正确,键名是否重复,是否有不必要的冒号或格式错误。</think>--- **YAML 出现 `mapping values are not allowed in this context` 错误,通常由以下原因导致:** --- ### **1. 缩进错误** YAML 对缩进极其敏感,**所有同级键必须对齐**,且子属性需通过 **2 空格**(或固定空格数)缩进。 **错误示例:** ```yaml services: db: image: mysql:5.7 volumes: # 错误!此处不应缩进 - db_data:/var/lib/mysql ``` **修正:** ```yaml services: db: image: mysql:5.7 volumes: # 与 image 同级对齐 - db_data:/var/lib/mysql ``` --- ### **2. 键值对格式错误** YAML 中键值对需用 `:` 分隔,且 **冒号后必须有空格**。 **错误示例:** ```yaml environment: MYSQL_ROOT_PASSWORD:somewordpress # 错误!冒号后缺少空格 ``` **修正:** ```yaml environment: MYSQL_ROOT_PASSWORD: somewordpress # 冒号后加空格 ``` --- ### **3. 列表项格式错误** 列表项需以 `-` 开头,且 **与父键对齐**。 **错误示例:** ```yaml volumes: -db_data:/var/lib/mysql # 错误!- 后需有空格,且缩进错误 ``` **修正:** ```yaml volumes: - db_data:/var/lib/mysql # - 后加空格,缩进对齐 ``` --- ### **4. 重复键名** YAML **不允许同一层级重复定义相同键名**。 **错误示例:** ```yaml services: db: volumes: [db_data:/var/lib/mysql] volumes: # 错误!重复定义 volumes - ./init.sql:/docker-entrypoint-initdb.d/init.sql ``` **修正:** ```yaml services: db: volumes: # 合并为同一键 - db_data:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql ``` --- ### **5. 特殊字符未转义** 若值中包含 `:`、`{`、`}` 等符号,需用引号包裹。 **错误示例:** ```yaml command: --init-file=/data:value # 冒号可能引发歧义 ``` **修正:** ```yaml command: "--init-file=/data:value" # 用双引号包裹 ``` --- ### **定位错误行号** 根据错信息 `line 13`,检查第 13 行附近的代码。 **常见问题场景:** - 第 13 行可能是一个键值对的冒号后缺少空格。 - 第 13 行的缩进与其父级不一致。 - 第 13 行意外使用了 `:`(如本应为列表项却写成键值对)。 --- ### **调试建议** 1. **使用 YAML 校验工具** 通过在线工具(如 [YAML Lint](https://www.yamllint.com/))或命令行验证: ```bash docker compose config # 检查 Docker Compose 语法 ``` 2. **检查缩进** 确保所有层级使用 **相同数量的空格**(推荐 2 空格,避免 Tab)。 3. **简化复杂结构** 若涉及多行命令或脚本,优先用列表形式(而非字符串): ```yaml entrypoint: - sh - -c - "/script.sh && exec main-command" ``` --- **示例修正(假设错误在第 13 行):** ```yaml # 错误行示例(line 13): command: --init-file /data/init.sql # 错误!应为列表格式 # 修正为: command: - "--init-file=/data/init.sql" # 列表项 + 合并参数 ``` 通过逐步排查格式问题,即可解决此错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值