Reputation: 1112
I know this has been discussed over and over (I have several implementations of my own on this matter), perhaps that is part of the reason I am asking: there is no definitive answer (after hours of searching) and I feel this is catch 22.
My setting is Spring Boot 1.3.6, which is "married" to Hibernate 4.3.11. I am using Spring Data JPA.
I have an entity which contains multiple collections of sub-entities, @OneToMany
and @ManyToMany
. That's the model -- it's not for me to love or hate.
Then I have a normal CRUD UI with a table of the main entity and an editor where the user gets to choose options for the sub-entities and save the main entity.
The UI is done with Vaadin and there are Web Sockets involved. So - not a normal Http exchange.
With the normal settings I get the "normal" LazyInitializationException from Hibernate. Because, once the entity is loaded in the table screen, the session is closed, so, when the collections are called in the editor screen, either I reload the entity altogether, which kind of kills all the mojo of using an ORM, or I try something else:
@Fetch(FetchMode=JOIN)
which shouldn't have been there in the first place)spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
to my startup config, which is basically the same as the first option, turned into a default. No, thank you.countingQuery
also (without join fetch), because otherwise you will get a nice, clear and easy to debug org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
. Also, if you "forget" to remove the fetchType
options on the @OneToMany
or @ManyToMany
annotations, you get another hair-pulling exception: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
Finally, switching to EclipseLink, which has the more sensible approach of simply requesting the sub-collections when needed, in a new session, seems more of a chore than Spring Boot usually offers (with several discussions still ongoing regarding the necessity to run the application with the instrumentation agent).
So, ultimately, is there a hack-free solution for this problem?
Upvotes: 2
Views: 1854
Reputation: 1974
There are two main strategies working with hibernate.
LazyInitializationException
after conn-close)The LazyInitializationException
gives us the hint that you are using short-lived-session
.
Either you use long lived session and use the entities in the view of the MVC. Or you remap all values from the entities to new wrappers who are not entities.
I would suggest to keep the short-lived-session
strategie and remap all values to pojos for the view. Because: The db-structure is rarely the information-structure you need in the frontend. In example:
You have two Entitys:
But in the View you have this Dataobject (DTO):
You see, the beans are different and you will not get a LazyInitializationException
after conn-close.
Upvotes: 2