2

I am migrating a huge project from Eclipselink to Hibernate JPA that running on Wildfly 10.0

Once moved to Hibernate I got the famous exception " failed to lazily initialize a collection of role "

I found many solutions for this issue like these suggestions on this Question as well as the old OpenSessionInView method.

But these solutions are somehow outdated, and needs some changes on my running existing code that use eclipselink.

Is their a newer, modern, transparent solution that can save my time ?

Note: I am not using spring (only JPA and EJB) .

Community
  • 1
  • 1
Samy Omar
  • 770
  • 14
  • 29
  • 2
    The source of the problem hasn't change in all that time so the solutions you find are still very relevant. JPA 2.1 added support for [entity graphs](http://www.thoughts-on-java.org/jpa-21-entity-graph-part-1-named-entity/) which are a more "modern" solution - that still requires you to refactor code. There are no time savers I'm afraid, other than switching back to EclipseLink which can work just fine on Wildfly 10. – Gimby Sep 30 '16 at 15:24

1 Answers1

3

I think you are looking for the hibernate.enable_lazy_load_no_trans configuration property. But that's an Anti-Pattern. Just because other JPA providers use it, it does not mean that it is efficient as well, or it's even appropriate.

Another bad way of "fixing" the LazyInitializationException is the Open Session in View, which is also an Anti-Pattern.

The best way to handle LazyInitializationException is to JOIN FETCH all one-to-one and many-to-one associations and up to a single one-to-many association.

If you need to fetch multiple one-to-many or many-to-many associations, then the first one should be JOIN FETCH-ed, while the subsequent ones should be initialized with a separate query. You can either navigate the association to trigger the initialization or use Hibernate#initialize.

Vlad Mihalcea
  • 103,297
  • 39
  • 432
  • 788
  • But why on earth did not hibernate team solve this old age problem ? Or in other words what benefits we get from not implementing this feature ? – Samy Omar Sep 30 '16 at 20:28
  • It has. By forcing you to reason how to fetch your associations, you're going to get optimal performance. "Fixing it" with OSIV or temporary Session, which are also supported by Hibernate, is not really a solution. There's no Silver Bullet. – Vlad Mihalcea Sep 30 '16 at 20:34
  • On the other hand, Eclipselink made a magical solution that give the developer the option of accessing any lazy list whenever he needs without writing named queries with JPQL that use JOIN FETCH , Moreover it does not compromise the performance. – Samy Omar Oct 01 '16 at 00:23
  • EclipseLink will have to use a separate connection for fetching those associations. Check out the connection pool logs to validate it. Have you profiled the association loading to make sure that it does not affect performance? Try building a test where you fetch 10 associations before the EntityManager is closed and one test when associations are fetched after EM is closed. See which one is faster. – Vlad Mihalcea Oct 01 '16 at 04:25
  • Thanks, I will try your proposed test myself and well let you know. – Samy Omar Oct 01 '16 at 06:09
  • So, Are you sure that EclipseLink internal implementation is the same as Hibernate (when the property hibernate.enable_lazy_load_no_trans is TRUE) ? – Samy Omar Oct 04 '16 at 22:50
  • I'm not sure, but you can verify and tell me I'm wrong. – Vlad Mihalcea Oct 05 '16 at 05:45