spring如何允许延迟加载?

时间:2010-01-11 18:34:16

标签: java hibernate spring orm

如果您使用像(伪代码)这样​​的Dao方法进行调用:

返回..getHibernateTemplate(按id获取);

现在说实体有一个延迟加载的集合。一旦你使用hibernateTemplate帮助器方法从你的Dao返回,为什么会话保持在范围内并允许你延迟加载一个集合?

会话是基于每个请求在全局级别初始化和提交的吗?

更新

请详细说明“getcurrentsession”的确切调用,以及实际关闭/提交的时间?

据我所知,spring框架必须处理会话生命周期,它在哪里执行此操作?请求生命周期中的什么时候?

它也在处理工作单元,在哪里/如何?

4 个答案:

答案 0 :(得分:6)

  

使用hibernateTemplate帮助器方法从Dao返回后,会话如何保留在范围内并允许您延迟加载集合?

因为Session尚未关闭,因此您的实体仍然是 Persistent (而不是 Detached 对象状态)。只要您的实体未被分离,就可以延迟加载集合和代理。有关这些状态的更多详细信息,请参阅章节10.1. Hibernate object states(理解它们和使用的术语非常重要)。

  

会话是基于每个请求在全局级别初始化和提交的吗?

对于Web应用程序,通常是每个请求。正如HibernateTemplate的javadoc中提到的那样:

  

延迟加载也可以在事务内或OpenSessionInViewFilter / Interceptor中使用打开的Hibernate Session。

如果您查看OpenSessionInViewFilterOpenSessionInViewInterceptor的javadoc,您会看到它们略有不同,但将Hibernate会话绑定到整个的线程处理请求并提供“在视图中打开会话”模式的实现。

  

请详细说明“getcurrentsession”的确切调用,以及实际关闭/提交的时间?

您可以查看源代码并使用调试器,您知道:)查看HibernateTemplate,更确切地说是doExecute()方法,这是获取会话的地方。对于关闭/提交,请查看前面提到的OpenSessionInViewFilter / Interceptor,两者都有用于此目的的方法。

  

据我所知,spring框架必须处理会话生命周期,它在哪里执行此操作?请求生命周期中的什么时候?

我想我已经介绍了这一部分:会话是在请求开始时创建的,最后是关闭的。

  

它也在处理工作单元,在哪里/如何?

我不确定能得到这个。对我来说,Hibernate的Session 工作单元模式的实现。所以这个问题实际上与前一个问题相同。

PS:我提供了一些链接,表明一切都是清楚记录的。 Spring和Hibernate有非常好的文档和javadoc。利用它,自己查看它们,自己查看代码,使用调试器,你将学到更多。

答案 1 :(得分:1)

Hibernate返回集合的a custom implementation,只有在调用任何集合方法时才执行加载。这个集合是以会话为参数构建的。

执行getSomeCollection().getClass()的sysout以查看它是哪个Hibernate自定义类,并检查相应的javadocs / sourcecode以查看它们是如何完成的。

如果你质疑接口的意义/用途/价值并声明接口,现在,这个是一个好的示例。你没有看到任何东西,是吗? ;)

答案 2 :(得分:1)

  

会话是基于每个请求在全局级别初始化和提交的吗?

它通常使用...(等待它)按请求进行初始化

  

请详细说明“getcurrentsession”的确切调用,以及实际关闭/提交的时间?

它:org.springframework.orm.hibernate3.HibernateTemplate

...是Spring与Hibernate集成的核心。 HibernateTemplate将根据需要初始化会话(或从ThreadLocal存储中提取已存在的会话)并将其提供给您为HibernateTemplate#execute *方法提供的任何回调。

  

据我所知,spring框架必须处理会话生命周期,它在哪里执行此操作?请求生命周期中的什么时候?

也由HibernateTemplate完成,并且......

  

它也在处理工作单元,在哪里/如何?

由HibernateTransactionManager完成,如果你在applicationContext中配置了一个。

答案 3 :(得分:0)

如果这是一个Web应用程序,我会使用OpenSessionInViewFilter