How to get rid of LazyInitializationException with Wicket JPA/Hibernate integration (with Spring)
i'm developing an application using Wicket as the view layer and JPA(Hibernate) as ORM. building the UI has been fun (even with ajax) using Wicket. My problem comes from integrating the persistent objects on edit pages (readonly pages are no problem using a LoadadableDetachableModel).
I'm using the OSIV filter from spring to provide an open session for the view. But, as i keep the domain objects (the @Entity mapped classes) in the edit pages, i get the dreaded Lazy loading excetion when i access properties of them in ajax callbacks.
i don't really want to go down the DTO / VO road, as i think it would only bloat the code and requires me to write lots of boiler-plate code.
One idea was to use the model objects in the view, merge the passed in object with the current hibernate session and access all getters to fully initialize the object. after this, the object would be stored in the view (seesion) and become detached. Upon save, i would re-merge it and commit the change.
Would this be an recommended way? Are there better solut开发者_运维技巧ions? Strange enough, most books / blogs / howtos completely ignore such issue.
What transaction management would you suggest? Right now i use @Transaction at the service layer. How would that change if i use other ways of accessing storing the data across hibernate sessions?
Any pointers / Links are welcomed as i'm kind of lost here..
thanks in advance
This blog post (that goes into the details of LDM) gave me some good insights especially for edit scenarios:
Building a smart EntityModel
FWIW I had very good results using a custom RequestCycle (as suggested in the comments section of the link above) in PerfBench and you can find the code here. IIRC this is a simplification of the approach (OpenSessionInView / London Wicket) from the link Bozho posted.
This is a short presentation on OpenSessionInView with Wicket.
If used properly, the OpenSessionInView approach should guarantee that no LazyInitializationException
occurs.
I finally had time to work on that problem again. Don 't know how i could have missed the simple solution ;)
We had developed our own UIFormModel
implementation of the Wickets IModel Interface. Since i wanted to keep the user input during http requests, i did nothing in the detach() call, keeping (and serializing) the model object in full state.
All i had to add was a flag that detach() was called and check that flag in the getObject()
method. If the flag was set, i do a EntityManager.merge()
and have a reattached model that i can use in the UI components.
Thanks all for your input
If you use LoadadableDetachableModel's that you do not pass to a component as the model, then wicket will not call .detatch() on them, and often they are not serialzied either, so they will have old data, and throw the lazy exception.
Make sure to always pass LDM to a component, or detach them yourself.
精彩评论