Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何关闭&;如果出现异常,请打开新的Hibernate会话_Java_Hibernate_Spring Mvc_Spring Transactions_Open Session In View - Fatal编程技术网

Java 如何关闭&;如果出现异常,请打开新的Hibernate会话

Java 如何关闭&;如果出现异常,请打开新的Hibernate会话,java,hibernate,spring-mvc,spring-transactions,open-session-in-view,Java,Hibernate,Spring Mvc,Spring Transactions,Open Session In View,上下文/设置 我们在应用程序中使用会话过滤模式中的开放会话,并集成了Spring和Hibernate 我们使用org.springframework.transaction.interceptor.TransactionProxyFactoryBean使用Springs声明性事务管理 当应用程序收到请求时,我们执行多个数据库活动(插入/更新),其中更新和插入分别刷新到数据库并提交事务 问题 假设其中一个insert/update发生数据库异常,hibernate会话按预期关闭,因为会话处于无效状

上下文/设置

我们在应用程序中使用会话过滤模式中的开放会话,并集成了Spring和Hibernate

我们使用
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
使用Springs声明性事务管理

当应用程序收到请求时,我们执行多个数据库活动(插入/更新),其中更新和插入分别刷新到数据库并提交事务

问题

假设其中一个insert/update发生数据库异常,hibernate会话按预期关闭,因为会话处于无效状态

即使在这之后,如果我不想返回请求,想继续我的请求并完成其他活动,我也不能,因为会话已关闭,并且通过此会话的任何连续调用都失败,原因显而易见

我需要帮助来编写一个解决方案,在这个解决方案中,我可以关闭现有会话并打开一个新会话,并使用
TransactionSynchronizationManager
将最新的会话附加到线程,但我不确定如何执行此操作,因为在流程中有许多地方可能需要执行此操作,是否有一种通用的方法来执行此操作?它的设计是否正确

即使我实现了这一点,那么与前一个会话分离的实体如何自动连接到新会话以便代理无缝工作呢

我们正在我们的应用程序中使用会话过滤模式中的开放会话 应用程序与Spring和Hibernate集成

对话模式与JavaEE中的扩展持久性上下文类似,其工作原理与您在这里描述的一样。如果你得到一个例外,你将不得不放弃一切,从头开始

现在,如果您想要更大的灵活性,您可以只使用分离的实体,并在每个请求中使用一个新的
会话
,该会话将合并分离的实体

但是,如果一个实体状态总是导致异常,该怎么办?如何确定实体并忽略它?如果它链接到其他实体呢

因此,这个问题没有简单的解决办法。您可以做的是:

  • 使用从数据库读取的初始实体捕获初始状态,并将其存储在
    HttpSession
    、Redis等中
  • 存储用户提交的信息,因此如果出现异常,可以使用与错误消息相同的更改重新呈现UI

  • 这样,用户不会丢失他们所做的更改,并且根据错误消息,他们可以在应用更正后重试。

    感谢Vlad的快速回复。我指的是一个不同的问题,在这个问题上,即使我的一个更新失败,我仍希望继续执行相同的请求,并继续执行其他活动,但是为了做到这一点,我需要创建一个新会话并将所有实体附加到它。是否需要手动执行此操作,因为我可能没有旧会话的所有实体的跟踪?是否有一个公共场所/模板类,我可以在其中创建此会话,以便我的任何事务失败我应该创建一个新会话?是的,您必须手动执行此操作。这就是为什么你最好还是照我的建议去做。