在长时间运行的对话中,在Wicket和Hibernate之间安全地传递信息

时间:2010-05-27 09:40:14

标签: hibernate wicket

我们在后台使用Wicket和Hibernate。

作为外部用户界面的一部分,在将更新的信息写回数据库之前,我们有很长的运行时间跨越多个请求。

为了避免因分离对象而出现休眠错误,我们现在使用值对象将信息从服务层传输到Wicket。

然而,我们现在最终爆炸了几乎相同的物体:

e.g。

  • 答案(保存在休眠中的映射实体)
  • AnswerVO(不可变值对象)
  • AnswerModel(会话域中的可变bean)
  • IModel包裹Wicket模型
  • 通常将其包含在CompoundPropertyModel

当对象中涉及到其他对象的集合时,这种管道会变得指数级变差。

必须有更好的方法来组织它。

任何人都可以分享一些提示,以减少繁琐吗?

也许让值对象变得可变,这样我们就可以在Wicket中删除对seaprate backing bean的需求了吗?

使用实体bean,但绝对要确定它们是否与hibernate分离。 (说起来容易做起来难过)?

其他一些技巧或模式?

2 个答案:

答案 0 :(得分:3)

使用Spring的OpenSessionInViewFilter。这将帮助您按请求创建hibernate会话。但是,它只打开一个只读会话。要对您的实体bean执行任何写操作,我建议启动一个hibernate事务(您可以使用Spring中的TransactionTemplate)。还有其他方法可以执行写操作,但我发现这对我来说最简单。

现在,要清理你的豆子,这就是我倾向于做的事情

  1. 只有实体bean
  2. 如果您想要无状态,只需将实体bean的密钥保存到会话中,并在多请求会话中的每个请求上重新加载bean
  3. 保持有状态是一个小问题。您需要在将bean保存到会话存储中之前分离您的实体bean ,并且在执行后续请求时您需要重新附加它。当然,如果有人在后台更新了实体,您将不得不在应用程序中处理它(即通知用户“数据库已在外部修改,等等”。)
  4. 我会选择上面的(2),因为它非常简单,适用于大多数情况。当您的持久性bean被两个单独的会话修改时,不推荐使用它,因为您最终会覆盖以前的更新。

    Hibernate确实有some documentation on dealing with detached objects

答案 1 :(得分:2)

通常的解决方案是视图“模式”中的开放会话,参见例如osiv with wicket

我对OSIV没有很好的经验,所以我建议在GUI层下设置事务边界,并在业务或服务层中通过巧妙的计划数据检索解决臭名昭着的lazyInitializationException