如何通过使用Spring集成Wicket JPA/Hibernate来解决LazyInitializationException问题

7
我正在使用Wicket作为视图层和JPA(Hibernate)作为ORM开发应用程序。使用Wicket构建UI非常有趣(即使使用ajax)。我的问题来自于在编辑页面上集成持久化对象(使用LoadadableDetachableModel的只读页面没有问题)。
我使用Spring的OSIV过滤器为视图提供开放会话。但是,由于我在编辑页面中保留了域对象(@Entity映射类),所以当我在ajax回调中访问它们的属性时,我会遇到可怕的延迟加载异常。
我不想走DTO/VO路线,因为我认为这只会使代码膨胀,并要求我编写大量样板代码。
一个想法是在视图中使用模型对象,将传入的对象与当前的Hibernate会话合并,并访问所有getter以完全初始化对象。之后,对象将被存储在视图(会话)中并变为分离状态。保存时,我将重新合并它并提交更改。
这是一种推荐的方法吗?有更好的解决方案吗?奇怪的是,大多数书籍/博客/教程都完全忽略了这个问题。
您建议使用什么事务管理?现在我在服务层使用@Transaction。如果我使用其他方式访问存储跨Hibernate会话的数据,那会怎样改变?
如果您有任何提示/链接,欢迎提供,因为我有点迷失了。
提前感谢。

我修改了你的问题标题,以便它反映出真正的问题。 - Bozho
谢谢提供链接。我已经开始深入研究源代码/ javadoc,目前看起来很不错。我甚至知道WicketRAD,但在考虑这个问题时它不知怎么就被忽略了。 - bert
4个回答

6
这篇博客文章(深入介绍了LDM的细节),特别是对于编辑场景,给了我一些很好的见解: 构建智能EntityModel 顺便说一句,在PerfBench中,我使用了自定义的RequestCycle(正如上面链接的评论部分所建议的),效果非常好,你可以在这里找到代码。如果我没记错,这是来自Bozho发布的链接的简化方法(OpenSessionInView / London Wicket)。

3

这份简短的介绍涉及到了Wicket中的OpenSessionInView。

如果正确使用OpenSessionInView方法,应该可以保证不会出现LazyInitializationException异常。


1

我终于有时间再次解决那个问题了。不知道我怎么可能会错过这么简单的解决方案 ;)

我们开发了自己的 UIFormModel 实现 Wickets IModel 接口。由于我想在 http 请求期间保留用户输入,所以在 detach() 调用中什么也没做,保持(和序列化)模型对象处于完整状态。

我所需要添加的就是一个标记表明已调用 detach() 并在 getObject() 方法中检查该标记。如果设置了该标记,则执行 EntityManager.merge() 并获得重新附加的模型,可以在 UI 组件中使用。

感谢大家的帮助。


0

如果您使用 LoadableDetachableModel,但没有将其作为模型传递给组件,则 Wicket 不会在其上调用 .detach() 方法,而且它们通常也不会被序列化,因此它们将包含旧数据并抛出 lazy 异常。

请务必始终将 LDM 传递给组件或自行分离它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接