【发布时间】:2015-03-19 17:36:23
【问题描述】:
我正在使用 hibernate 4.3 和 SWF 2.4,在特定情况下遇到了一个奇怪的行为,导致 LazyInitializedException。
这是流程的配置:
<persistence-context />
<on-start>
<!-- attach enterprise to session if not provided -->
<evaluate expression="enterpriseInput ?: enterpriseDaoImpl.merge(externalContext.sessionMap.workingEnterprise)" result="flowScope.enterprise"/>
</on-start>
<view-state id="start" view="filiation/list">
<transition to="showBoardOrGoToList" on="save" />
</view-state>
<action-state id="showBoardOrGoToList">
<evaluate expression="flowController.displayBoard(event)" />
<transition on="yes" to="boardSubflow"/>
<transition on="no" to="something" />
</action-state>
<subflow-state id="boardSubflow" subflow="board">
<on-entry>
<evaluate expression="boardFlowController.initAdmins(enterprise)" result="flowScope.admins" />
</on-entry>
<input name="admins" value="flowScope.admins"/>
<output name="enterprise" value="flowScope.enterprise"/>
<transition on="save" to="end">
<evaluate expression="enterpriseDaoImpl.merge(enterprise)" result="flowScope.enterprise"/>
</transition>
<transition on="cancel" to="cancel"/>
</subflow-state>
...
当流量到达以下行时:
<evaluate expression="boardFlowController.initAdmins(enterprise)" result="flowScope.admins" />
它会触发一个 LazyInitializedException,方法 initAdmins() 基本上是对列表的元素执行 Hibernate.initialize()。
for (Administrator administrator : enterprise.getAdministrators()) {
Hibernate.initialize(administrator);
}
如果在该行之前调用了 DAO 上的方法,它将毫无问题地执行 DB 查询,这意味着此时休眠会话可用,但lazyInit 不起作用。
但是,如果我在流程的 <on-start> 标记中调用 initAdmins(),它可以工作...
有效的流程配置:
<persistence-context />
<on-start>
<!-- attach enterprise to session if not provided -->
<evaluate expression="enterpriseInput ?: enterpriseDaoImpl.merge(externalContext.sessionMap.workingEnterprise)" result="flowScope.enterprise"/>
<evaluate expression="boardFlowController.initAdmins(enterprise)" result="flowScope.admins" />
</on-start>
<view-state id="start" view="filiation/list">
<transition to="showBoardOrGoToList" on="save" />
</view-state>
<action-state id="showBoardOrGoToList">
<evaluate expression="flowController.displayBoard(event)" />
<transition on="yes" to="boardSubflow"/>
<transition on="no" to="something" />
</action-state>
<subflow-state id="boardSubflow" subflow="board">
<input name="admins" value="flowScope.admins"/>
<output name="enterprise" value="flowScope.enterprise"/>
<transition on="save" to="end">
<evaluate expression="enterpriseDaoImpl.merge(enterprise)" result="flowScope.enterprise"/>
</transition>
<transition on="cancel" to="cancel"/>
</subflow-state>
...
问题是我只想在需要时初始化管理员,因为这是一项昂贵的操作。
关于持久性上下文机制的信息很少,所以我找不到对此的解释。
对我来说,它真的看起来像一个错误。
有人可以强调我或解释为什么lazyInit 在on-start 标记之外被破坏了吗? 谢谢
【问题讨论】:
-
我遇到了类似的问题。我不得不将我的项目列表更改为 Set 并覆盖 equals/hashCode。
标签: java hibernate lazy-initialization spring-webflow-2