3

I'm using JPA2.1 and hibernate 4.3.8 and i have configured the presistence.xml to allow lazy loading

i have added

<property name="hibernate.enable_lazy_load_no_trans" value="true" />

into properties section

but i'm still getting LazyInitializtionException, what is the problem ?

Amr Khaled
  • 41
  • 3
  • 8

2 Answers2

9

The hibernate.enable_lazy_load_no_trans is an anti-pattern and you should never use it because a database connection is needed for every lazy association that is fetched outside of the initial Persistence Context, and that's going to put pressure on the underlying transaction log and the JDBC connection pool.

More, the hibernate.enable_lazy_load_no_trans is prone to N+1 query issues.

Sometimes, you don't even need entities, and a DTO projection is even better.

Vlad Mihalcea
  • 103,297
  • 39
  • 432
  • 788
  • 3
    "never use it" -> "avoid if possible". This parameter was the best option for our use case (max 20 users, big entity graph that gets 100% displayed in a GUI (in tabs, tooltips & dialogs)). – AndrewBourgeois Jul 19 '17 at 08:45
  • Just because you don't have a typical enterprise concurrency or data requirements, it does not mean that this setting will buy you a lot. As I explained in the links attached to this answer, the `LazyInitializationException` is a code smell related to the data access layer design. Most often, entities are fetched for read-only views even if DTOs would suffice. Remember that entities are only needed if you plan on modifying them. Otherwise, you're just burning DB resources to fetch more columns than necessary. – Vlad Mihalcea Jul 19 '17 at 09:43
  • In the real world most legacy projects have code smells like this and while I agree with all your points, you have to work with what you're given. This parameter was a real time-saver because it allowed me to simply switch the model to lazy loading to improve performance. 1 mwd vs 15 mwd to rework the whole thing. Read-only operations (to generate reports didn't use DTOs so the whole graph was eager loaded every time the reports needed an attribute of the main entity). – AndrewBourgeois Jul 19 '17 at 10:30
  • This parameter is needed only when you backport from EclipseLink which hides LIO behind the carpet and you want to switch to Hibernate. You enable this parameter so your app can work just like EclipseLink, and then start fixing the data access layer to fetch just as much as it needs on a per business use case. It's meant to be a temporary fix for when you move from EclipseLink. Otherwise, it's not recommended. That's why it's disabled by default. – Vlad Mihalcea Jul 19 '17 at 10:45
  • 1
    Or if the previous team decided that it would be a good idea to eager load everything with Hibernate. Which worked fine in production for a while because the same data was edited over (= not a lot of new records). The problem only became apparent after a few years of slowly adding new records. I definitely wouldn't use that parameter in a new project but it did great for that old one. – AndrewBourgeois Jul 19 '17 at 11:00
  • 1
    Your book discourages Temporary Session Lazy Loading but doesn't tell us to never use it. This is the only thing that bothers me here as it was the best (= cost-effective) solution to our problem. – AndrewBourgeois Jul 19 '17 at 11:29
  • My book presents it as an Anti-Patterns. In my experience, I've never used any Anti-Pattern because it was cost-effective. However, that's just me. Spring Boot uses the [OSIV Anti-Pattern by default](https://github.com/spring-projects/spring-boot/issues/7107) because junior devs would probably find it more difficult to reason about fetching strategies. – Vlad Mihalcea Jul 19 '17 at 11:34
0

Try enter the "true" like this:

<property name="hibernate.enable_lazy_load_no_trans">true</property>

It work for me.

Mr Hoelee
  • 276
  • 1
  • 5
  • 19