我正在实现一种需要长时间运行的JobProcessor。这些作业使用的信息基本上是Page
,PageField
和PageRelation
,它们定义了一个页面树,每个页面都有自己的PageField
。
tl; dr如何轻松地从Hibernate复制Object结构以在事务外部使用?
更多细节:
我使用Hibernate来持久保存这些对象,一切正常。目前,我在VM中运行JobProcessor,我手动控制事务:
this.em.getTransaction().begin();
job.start();
this.em.getTransaction().commit();
我有时需要页面上的信息,我可以像这样检索它们:
this.em.getTransaction().begin();
Page page = this.withId(pageId)
this.em.getTransaction().commit();
不知何故,我很幸运,我从未遇到过LazyInitialization异常;我相信因为HibernateSession永远不会关闭。
现在我正在转向Spring控制的环境,并试图让所有交易变得简短而干净。我需要Page
的对象树,即长期运行方法中的所有字段,关系和字段。我认为最好的方法是制作树的防御性副本。如何轻松实现这一目标?或者有更好的方法来解决这个问题吗?
答案 0 :(得分:1)
就像你说的那样,Hibernate试图在你需要之前暂停获取数据,这对性能有利。
以下是一些解决方案:
1)如果你知道你总是需要页面的整个树,你可以使用一个带有fetch join的Hibernate查询到你需要的子实体(而不仅仅是做session.get())。这将强制Hibernate填充子元素。
2)如果您首先需要每个页面的高级别信息,并且当用户采取某些操作时您只需要树的其余部分,例如单击特定页面,那么当用户选择该页面时在页面中,您可以使用页面ID来获取特定页面的子元素,也可能使用Hibernate查询。