如何使用 Spring 4.0.6 全局设置 Hibernate 4.3.5.Final 的 FlushMode?

2023-12-13

我正在尝试使用 Hibernate 4.3.5.Final 和 Spring 4.0.6 升级我们的应用程序。我的应用程序中任何具有数据库写入操作的位置都会出现如下错误:

Caused by: 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.
  at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1135)
  at org.springframework.orm.hibernate4.HibernateTemplate$26.doInHibernate(HibernateTemplate.java:826)
  at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:340)
  at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
  at org.springframework.orm.hibernate4.HibernateTemplate.deleteAll(HibernateTemplate.java:823)
  ... 

以下是我的 sessionFactory 和 transactionManager 的 spring 配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="mappingResources">
    <list>
      <value>com/mycompany/Person.hbm.xml</value>   
    </list>
  </property>
  <property name="hibernateProperties">
    <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
    </props>
  </property>
</bean>

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

1:

为了全局设置flushMode以使应用程序以与以前相同的方式工作,我需要全局将flushMode设置为AUTO,所以我不想使用@Transactional(readOnly = false)方法。

2:

在下面的帖子中,有人建议将 singleSession 设置为 false,Java / Hibernate - 只读模式下不允许写操作

Spring 文档表明指定“singleSession”=“false”有副作用:http://docs.spring.io/spring/docs/4.0.6.RELEASE/javadoc-api/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.html

3:

我在 web.xml 中看到了很多像下面这样的建议,它允许您拦截 hibernate3 会话并提供会话版本,例如冲洗模式.AUTO。但是,当您使用 org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 时,这在 hibernate 4 中不起作用。

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>flushMode</param-name>
        <param-value>AUTO</param-value>
    </init-param>
</filter>

4:

下面建议的方法是使用 JPA 事务管理器,它遵循 HibernateJpaDialect 的复杂重新实现。我目前没有使用 JPA,这种方法似乎不够简单。如何在配置文件中将刷新模式设置为“COMMIT”?

5:

我尝试在我的弹簧配置中使用以下内容(遵循关于Spring ORM 4.0.5 和 Hibernate 4.3.5 - 无法保存到数据库), 它似乎不起作用,人们建议使用 web.xml 方法:Spring和Hibernate突然将事务设置为只读

<tx:advice id="transactionAdvice" transaction-manager="transactionManager" >
  <tx:attributes>
    <tx:method name="*" read-only="false"/>
  </tx:attributes>
</tx:advice>

问题:

任何人都可以建议一种简单的方法来允许为 Hibernate 4.3.5.Final 和 Spring 4.0.6 设置 FlushMode 吗?


我最终用自定义实现覆盖了 OpenSessionInViewFilter :

1:

web.xml:

<filter>
  <filter-name>openSessionInViewFilter</filter-name>
  <filter-class>com.mycompany.AutoFlushOpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>openSessionInViewFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  • Spring 工作需要 ContextLoaderListener。
  • AutoFlush OpenSessionInViewFilter 用于拦截来自 /* url 模式的请求

2:

自动刷新 OpenSessionInViewFilter:

import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate4.support.OpenSessionInViewFilter;

public class AutoFlushOpenSessionInViewFilter extends OpenSessionInViewFilter {

  protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
    try {
      Session session = sessionFactory.openSession();
      session.setFlushMode(FlushMode.AUTO); // This line changes the default behavior
      return session;
    } catch (HibernateException ex) {
      throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
    }
  }
}
  • OpenSessionInViewFilter 是拦截 hibernate 会话的默认方式(http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.html)
  • openSession 方法打开一个休眠会话。 Hibernate 将使用此会话而不是创建新会话
  • hibernate3.support.OpenSessionInViewFilter 允许您提供 FlushMode,hibernate4.support.OpenSessionInViewFilter 硬编码该值,因此我用自己的实现覆盖它
  • 确保您的 sessionFactory bean 名称是 sessionFactory。否则,您需要将 sessionFactoryBeanName 设置为 web.xml 中的过滤器 init-param

3:

所有 Spring bean 都需要在 Web 应用程序上下文 (web.xml) 中注册:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath:appContext.xml
    ...
  </param-value>
</context-param>

4:

确保仅在需要使用 spring bean 时从应用程序上下文中获取它们。下面是一个如何示例:http://sujitpal.blogspot.co.uk/2007/03/accessing-spring-beans-from-legacy-code.html

确保只创建一份 Spring bean 副本! 如果您使用 org.springframework.context.support.ClassPathXmlApplicationContext 加载 Spring bean,这些 bean 将不会被过滤器选取。

5:

就我而言,还需要 contextId

<context-param>
  <param-name>contextId</param-name>
  <param-value>myApp</param-value>
  <description>Required contextId when filter is supplied</description>
</context-param>

否则我会遇到以下问题:

2014-09-02 10:59:50 StandardContext[/myApp]Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.NoSuchMethodError: javax.servlet.ServletContext.getContextPath()Ljava/lang/String;
  at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384)
  at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
  at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
  at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3827)
  at org.apache.catalina.core.StandardContext.start(StandardContext.java:4343)
  at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:823)
  at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:807)
  at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:595)
  at org.apache.catalina.core.StandardHostDeployer.addChild(StandardHostDeployer.java:903)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:216)
  at org.apache.commons.digester.SetNextRule.end(SetNextRule.java:256)
  at org.apache.commons.digester.Rule.end(Rule.java:276)
  at org.apache.commons.digester.Digester.endElement(Digester.java:1058)
  at org.apache.catalina.util.CatalinaDigester.endElement(CatalinaDigester.java:76)
  at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
  ...

如果有人感兴趣,以下是我的 Ivy.xml 中的内容

<!--Spring 4.0.6.RELEASE -->
<dependency org="org.springframework" name="spring-aop" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-beans" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-core" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-expression" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-context" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-jdbc" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-orm" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-tx" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="org.springframework" name="spring-web" rev="4.0.6.RELEASE" conf="compile->master,sources,javadoc"/>
<dependency org="aopalliance" name="aopalliance" rev="1.0" conf="compile->master,sources,javadoc"/>

<!--Hibernate 4.3.5-->
<dependency org="org.hibernate" name="hibernate-core" rev="4.3.5.Final" conf="compile->master,compile,sources"/>
<dependency org="net.sf.ehcache" name="ehcache-core" rev="2.4.8" conf="compile->master,sources,javadoc"/>
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->master,sources,javadoc"/>

希望这对在升级 Spring 和 Hibernate 时遇到相同问题的人有所帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Spring 4.0.6 全局设置 Hibernate 4.3.5.Final 的 FlushMode? 的相关文章

随机推荐

  • 通过 svg 路径滚动移动图像

    我想通过滚动上的 svg 路径移动对象 我试图将滚动上的部分路径添加到路径中 但它仍然不起作用 救命 https jsfiddle net YuriiBielozertsev Ltx9ed0L
  • ColdFusion 表单中的复选框

    我的代码如下 页面加载时 我需要默认选中这两个复选框 这将显示查询的结果 现在 当取消选中其中一个复选框时 需要提交表单并需要显示不同的查询结果 即使我取消选中复选框 这些复选框也始终会被选中 有人可以在这里指导我吗
  • 如何在java spring boot中将字节数组作为内存文件返回?

    我有一个字节数组作为数据 现在 如何使用 Spring Boot 编写一个控制器方法来将此字节数组作为文件返回 如果我用这个字节数组数据创建一个文件 那么我还应该删除它 对吗 有没有办法将此字节数组作为文件发送 而不必在我的项目中物理创建文
  • 如何获取相机应用程序的包名

    感谢之前的回复 是否可以获取设备上安装的相机应用程序的包名称 如果操作系统是自定义的 则默认包名称将由设备制造商更改 如何通过编码获取包名 我不确定这是否可能 你尝试过这个吗 PackageManager packman getPackag
  • 将绘图打印/保存为 png 文件,并在 Octave 中出现 alpha 通道问题

    如何将绘图打印 保存为带有 Alpha 通道的 png 文件 I tried 在具有透明背景的 Octave 中保存绘图 我正在使用 Octave 4 2 2 Ubuntu 18 04 64 位和graphics toolkit fltk
  • 通过 python-ldap 使用 Active Directory 中的 unicode 编码字符串

    我已经提出了这个问题 但经过一些测试后 我决定创建一个包含一些更具体信息的新问题 我正在使用 python ldap 和 Python 2 7 从我们的 Active Directory 读取用户帐户 这确实有效 但我对特殊字符有问题 当打
  • 将图像保存到媒体库 WP7

    我无法将图像保存到 Windows Phone 媒体库中 这是我的代码片段 public void SaveImageTo string fileName fileName jpg var myStore IsolatedStorageFi
  • Firestore 中可以使用多少个集合文档对?

    我有一个具有以下架构的应用程序 HOME gt Collection gt Document gt Collection gt Document 和代码 db collection coll doc doc collection subco
  • 元更改事件未触发

    我有一家商店 看起来像这样 Ext define GridGeneral store GridGeneralStore extend Ext data Store model GridGeneral model GridGeneralMod
  • 获取其他收件箱的参考

    我正在使用 Outlook 2007 并且有我的主邮箱 Tait Mark 我还在我的个人资料中添加了另一个邮箱 采购 请求 两者都显示为 Outlook 中的顶级文件夹 邮箱 泰特 马克 gt 对话历史记录 删除的项目 草稿 收件箱 垃圾
  • 在 WCF 中处理图像

    我有一个桌面应用程序 需要通过 TCP 协议向服务计算机上传 下载图像 起初 我将图像存储在文件系统中 但我需要在 MS SQL DB 中比较哪种解决方案更好 图片数量超过五十万 我还不知道照片尺寸是否有限制 如果您曾经这样做过 请写下您对
  • 在 JavaScript 中更改另一个函数中的变量

    我对 JavaScript 还很陌生 并且对变量和函数的一些属性遇到了麻烦 我想要发生的是有一个var在一个函数中定义 在另一个函数中更改值 然后将新值返回到最初定义它的函数 这是我制作的一个简单示例 function getIt var
  • 文本排序顺序的 MIN/MAX

    在 SQL Server 中 MIN 和 MAX 可以作用于不计算为数字的文本 返回具有最低或最高文本排序顺序的文本项 或者如 SQL Server 中所说的 排序顺序 是否可以在 Excel 中执行此操作 而无需使用实际排序的 UDF 例
  • malloc 和 calloc 与 std::string 之间的区别

    我最近开始接触 C 并且在使用 malloc 时遇到了问题 下面的代码不会打印出 成功 程序崩溃 退出代码为 0xC0000005 而如果我使用 calloc 则一切正常 int main std string pointer std st
  • 为什么使用 boost::multi precision::cpp_int 会影响这里的尾调用优化

    我有一些模板化代码 编译器可以对大多数数据类型进行尾部调用优化 但不能对其他数据类型进行尾部调用优化 代码实现了pow template
  • 如何在 gnuplot 中对箱线图异常值进行分组

    我有大量数据点 我尝试用箱线图绘制它们 但一些异常值是完全相同的值 并且它们表示在彼此旁边的一条线上 我发现如何设置gnuplot箱线图中异常值之间的水平距离 但这并没有太大帮助 因为这显然是不可能的 是否可以将异常值分组在一起 打印一个点
  • 如何撤消对 vim 中文本块的所有更改?

    是否可以选择一些带有视线的文本并撤消从一开始对其所做的所有更改 实际上 我是通过撤消所有拉动块的操作 然后将所有内容重做到最后一次修改 然后用拉动的文本替换该块来实现的
  • 如何从 Java 函数返回值?

    我正在尝试让以下程序运行 public class funWithNumbers public static void main String args int ten 10 int subend 7 int result ten sube
  • Android 图像位于 /assets 或 res/raw

    如果我想将一堆图像放入文件夹结构中 例如 我正在构建一个海滩应用程序 每个海滩都通过我的海滩详细信息活动显示 具体取决于从我的海滩列表中选择的海滩 然后我想显示来自该特定海滩的五张图像 每个海滩都会有一个文件夹 其名称与海滩的 id 相对应
  • 如何使用 Spring 4.0.6 全局设置 Hibernate 4.3.5.Final 的 FlushMode?

    我正在尝试使用 Hibernate 4 3 5 Final 和 Spring 4 0 6 升级我们的应用程序 我的应用程序中任何具有数据库写入操作的位置都会出现如下错误 Caused by org springframework dao I