如何摆脱与Wicket JPA / Hibernate集成的LazyInitializationException(使用Spring)

时间:2010-01-18 11:27:09

标签: hibernate spring jpa wicket

我正在使用Wicket作为视图层和JPA(Hibernate)作为ORM开发应用程序。使用Wicket构建UI非常有趣(即使使用ajax)。我的问题来自于在编辑页面上集成持久对象(使用LoadadableDetachableModel只读页面没有问题。)

我正在使用spring的OSIV过滤器为视图提供一个打开的会话。但是,当我在编辑页面中保留域对象(@Entity映射类)时,当我在ajax回调中访问它们的属性时,我得到了可怕的延迟加载。

我真的不想走DTO / VO之路,因为我认为它只会使代码变得臃肿,并且需要我编写大量的样板代码。

一个想法是在视图中使用模型对象,将传入的对象与当前的hibernate会话合并,并访问所有getter以完全初始化对象。在此之后,对象将存储在视图(seesion)中并变为分离。保存后,我会重新合并并提交更改。

这是推荐的方式吗?有更好的解决方案吗?奇怪的是,大多数书籍/博客/ howtos完全忽略了这样的问题。

您会建议什么交易管理?现在我在服务层使用@Transaction。如果我使用其他方式访问跨hibernate会话存储数据,会如何改变?

任何指针/链接都受欢迎,因为我有点迷失在这里..

提前致谢

4 个答案:

答案 0 :(得分:6)

这篇博文(详细介绍了LDM)给了我一些很好的见解,特别是对于编辑场景:

Building a smart EntityModel

FWIW我在PerfBench中使用自定义RequestCycle(如上面链接的评论部分所示)获得了非常好的结果,您可以找到代码here。 IIRC这是一个简化的方法(OpenSessionInView / London Wicket),来自Bozho发布的链接。

答案 1 :(得分:3)

This是关于Wicket的OpenSessionInView的简短介绍。

如果使用得当,OpenSessionInView方法应该保证不会发生LazyInitializationException

答案 2 :(得分:1)

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

我们开发了自己的Wickets IModel接口UIFormModel实现。由于我想在http请求期间保持用户输入,我在detach()调用中没有做任何事情,保持(和序列化)模型对象处于完全状态。

所有我必须添加一个标记,称为detach()并在getObject()方法中检查该标志。如果设置了标志,我会执行EntityManager.merge()并重新连接模型,我可以在UI组件中使用。

感谢大家的投入

答案 3 :(得分:0)

如果使用LoadadableDetachableModel,你没有将组件作为模型传递给组件,那么wicket就不会对它们调用.detatch(),并且它们通常也不会被序列化,所以它们会有旧数据,并抛出懒惰异常。

确保始终将LDM传递给组件,或自行分离。