【问题标题】:Hibernate's session-per-conversation & query unflushed entitiesHibernate 的会话会话和查询未刷新的实体
【发布时间】:2010-11-03 22:13:43
【问题描述】:

这是上下文:

我们目前正在编写一个基于 Web 的应用程序(flex 前端)。服务器端使用 Java 实现,使用 Hibernate for ORM。
该应用程序的特殊性在于它实现了与用户的对话。这意味着用户正在打开一个对话,并且在决定保存(或取消)对话之前,它会对映射为休眠实体的对象执行许多操作。

例如:

  • 打开对话
  • 创建一个对象A
  • 将其保存在会话中
  • 查询
  • 更新它
  • 等等……
  • 保存会话(刷新会话...)

然后另一个对话周期开始了。

我们自然而然地选择了每次会话会话模式来实现这种工作方式。
让我提醒你一个原则:
当用户决定开始对话时,会创建一次休眠会话,它的刷新模式设置为手动,从现在开始,每个事务之间都会断开连接,直到用户决定结束对话,这是我们唯一一次显式刷新会话(因此将数据从会话写入数据库)。


编辑
在每会话会话模式中,每个操作都是在提交的事务中进行的。例如,假设我们有两个服务,一个称为 addObject(),另一个称为 getObject()。
流程如下:

  • 打开一个对话(=> 会话是在刷新模式设置为 MANUAL 的情况下创建的,并将其绑定到持有当前会话的 ManagedSessionContext 中)
  • 调用 addObject() 服务获取会话会话、打开事务、创建实体、保存实体、断开会话并最终提交事务
  • 调用 getObject() 服务获取会话会话、打开事务、获取对象、断开会话并最终提交事务
  • 通过打开事务、刷新会话然后提交事务来保存对话。

在这里我们看到我无法在不提交事务的情况下刷新会话,因为目标正是在每个类似服务的操作之后提交事务。


在我们想要查询一些未刷新的实体之前,我们完全没有问题!因为如果我们想要使用这种对话,那是因为我们想要处于“模拟”状态,直到我们明确刷新会话。 但似乎无法使用休眠标准或 HQL 加载未刷新的实体,除非在会话上执行了 flush(),这会导致从会话每次会话模式中失去所有好处...

所以我的问题是:

我们可以配置这种行为吗? (即如果会话没有刷新,我们可以启用查询会话缓存事件吗?)

似乎答案是否定的(欢迎任何矛盾者!),第二个问题: 有没有一种聪明的方法可以让我自己做到这一点,而不会破坏可能聪明且被认为是 hibernate 的做事方式?

希望我的英语是可以理解的,在此先谢谢大家。 (让我准确地说,这个问题也已发布到休眠用户论坛)

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    来自 Hibernate API

    刷新是将底层持久存储与内存中保存的持久状态同步的过程。

    刷新并不一定意味着您将更改写入数据库。这意味着内存中的状态是最新的。 Flush 仅在您的数据库不支持事务或您不在事务中工作时将更改写入数据库。

    如果您使用事务并且您的数据库支持事务,例如带有 InnoDB 的 MySQL,那么您可以随时刷新,而无需向数据库写入任何内容。在您调用 Transaction.commit() 之前,更改不会写入数据库。

    【讨论】:

    • 感谢您的回答。我通过编辑我的问题增加了一些精度。实际上,我无法在不提交更改的情况下刷新会话,它是每会话会话操作方式的一部分。
    • 好的,我明白了。那么我的回答对解决你的问题没有多大帮助。对不起,误导了。
    猜你喜欢
    • 2013-10-08
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2014-02-18
    • 2016-06-03
    • 1970-01-01
    相关资源
    最近更新 更多