Java Hibernate会话及其作用域?

Java Hibernate会话及其作用域?,java,hibernate,service,Java,Hibernate,Service,我刚刚开始在HSQLDB中使用Hibernate。在教程中,他们告诉我不要使用反模式“每次操作会话”。但是,每次提交事务时,会话也会关闭。如果commit()关闭会话,我应该如何避免使用getCurrentSession() 我有点好奇人们通常如何处理会议的范围。我在构建web应用程序中看到了几个示例,其中每个请求有一个会话。在我的例子中,我正在构建一个服务,不能应用相同的想法。该服务全天候运行,偶尔会执行一些数据库操作。我应该让数据库会话始终保持活动状态,并且只使用事务作为操作之间的边界(考虑

我刚刚开始在HSQLDB中使用Hibernate。在教程中,他们告诉我不要使用反模式“每次操作会话”。但是,每次提交事务时,会话也会关闭。如果
commit()
关闭会话,我应该如何避免使用
getCurrentSession()

我有点好奇人们通常如何处理会议的范围。我在构建web应用程序中看到了几个示例,其中每个请求有一个会话。在我的例子中,我正在构建一个服务,不能应用相同的想法。该服务全天候运行,偶尔会执行一些数据库操作。我应该让数据库会话始终保持活动状态,并且只使用事务作为操作之间的边界(考虑到我的事务提交没有关闭会话的情况),还是应该为每个操作创建一个新的边界(这是反模式,但还有其他方法吗?)


提前谢谢

该行为由正在使用的应用程序的实现决定。默认值恰好是在提交时关闭的,但您决不受限于此

通过在生命周期的适当开始和结束时使用和绑定/解除绑定会话,可以配置/构建任何类型的会话作用域。您可以在入口将会话绑定到服务的工作单元,然后在出口将会话解除绑定,这对您来说似乎是有意义的。(当然,构建健壮的代码并不是一项简单的任务。尤其要记住,如果其中一个方法出现异常,您需要创建一个新的
会话


对评论的回应越来越大,无法发表评论

这是默认行为,因为它是唯一“安全”的东西,无需用户提供额外的工作或配置。“提交”是Hibernate在没有帮助的情况下能够“看到”的唯一生命周期点,因此它必须在那里关闭,否则会话将永远悬而未决

确定潜在的会话生命周期边界需要对您实际正在做的事情有相当多的了解。“这是一个后台服务”没什么可谈的。假设它做了一些事情,比如无所事事地坐着,每X分钟醒来一次,做一些工作,然后再睡X分钟,那么这将是打开然后关闭会话的一个很好的边界

当谈到“每个操作的会话”是一种反模式时,您可能使用了“操作”的过于宽泛的定义

他们的意思是不要做(对您的服务的虚构要求):

  • 叫醒服务
  • 公开会议
  • 从数据库读取文件位置
  • 闭门会议
  • 打开文件
  • 公开会议
  • 从当前文件状态更新数据库表
  • 闭门会议
  • 公开会议
  • 将活动日志写入数据库
  • 闭门会议
  • 睡眠服务

  • 在一次会议中这样做,然后在最后结束会议,这是完全合理的。在一个单线程环境中,您可以在已知边界内自己管理所有内容,如果需要,您可以自己打开和关闭会话,而无需使用
    currentSession
    。您只需要确保在发生异常时关闭它。如果您正在侦听操作系统事件,那么事件处理将是会话的一个完美范围。

    您是指守护进程意义上的“服务”,还是指仅以web以外的某种方式进行交互的外部使用者所使用的“服务”?我指的是守护进程意义上的“服务”,对不起,应该对此进行澄清。我明白了。如果默认的ThreadLocalSessionContext是反模式,为什么它是默认的ThreadLocalSessionContext?您的意思是,我应该在服务启动时使用getCurrentSession(),然后在关机时关闭它?回答不正确,评论太长谢谢您的详细解释!我改为ManagedSessionContext,但就我而言,这(到目前为止)几乎等同于将会话绑定到当前线程。如果不这样做,我必须将会话对象到处传递。我以后可能会想出一个更好的设计。。。非常感谢您的投入!将会话抛出到ThreadLocal中基本上是每个人最终都要做的:)这是OpenSessionInviewFilter所做的一切。