Spring Data JPA, Binding, Circular Models and LazyInitializationExceptions

I’m trying to mock up a quick proof of concept in Vaadin 10, and running into a brick wall that I’d rather not tunnel through…

I have a Hibernate-backed Spring Data JPA model that is, shall we say, legacy. Due to the way it was constructed, and grown over the years, it has many circular references. For example, a Person may have a collection of Groups he/she belongs to, and in turn each group has a collection of Person objects that are members of the group. Of course, the Groups collection from the Person object is fetched lazily.

I’m binding the Person object to a grid, and have it iterate the groups the person is a member of on the client side. (Kinda like how the bakery app enumerates the order items.)

Generally speaking, if you simply try to iterate through the Person bean and convert it to JSON you’ll hit a stack overflow due to the circular reference. So we annotate many of our collections with the Jackson @JsonIgnore annotation so they won’t get iterated. (In our REST/JSON APIs we have separate methods to retrieve those collections.)

That said, I hit 2 big problems with Vaadin 10. First, using binder.setItems() to bind to the Person object results in a LazyInitializationException as apparently the actual binding happens outside the flow of that call, so the JPA transaction is closed by the time that happens, giving the exception.

The second, the JSON parser doesn’t honor @JsonIgnore (I know It’s a Jackson tag, I didn’t see any other Vaadin-equivalents), and I’m forced to fully initialize or eagerly fetch all the collections, which is a massive performance hit. (Nevermind the circular reference and stack overflow that would arise.) I also don’t see any other way to readily substitute the JSON parser in Vaadin for something more malleable.

Short of either making “fake” objects of the same type with null collections, or creating entirely new beans just for the UI, I don’t see a simple solution. Any ideas?

Creating new DTOs for the UI would be the often recommended solution. This way you’re in control of bringing only the needed information to the UI layer as well as protecting yourself from any potential lazy-loading issues and such.

-Olli

I usually use Eclipselink (statically weaved entities) to avoid the LazyInitializationExceptions issue with Hibernate.

Fetching the collections does not have to be that expensive ( expect if the collections really contain large quantities of data… ), prefetch the collections using JPA join and fetch hints.

I don’t know how easy it is to switch Spring to Eclipselink but pure JPA is quite easy to switch between the two implementations, might be worth a try…

BTW, just saw that Hibernate also supports this…

Note that Hibernate 4.1.6 added support for loading lazy data outside transactions via the hibernate.enable_lazy_load_no_trans JPA property.

Thanks for the input. I had read about that property, but it seems a bit like an anti-pattern and was hoping to avoid it. Either way, it doesn’t get me past the circular reference problem with the JSON generator in Vaadin.