Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

476
Views
Lazy loading works, but shouldn't

The context of this question is within spring-boot, using spring-data-jpa and hibernate.

A colleague wrote an @Service and annotated the service method with @Transactional. The service method loads an entity, and subsequently hits a one-to-many lazily loaded collection (fetch = FetchType.LAZY). The service method is invoked by some custom delegator, which i will come back to. This works fine when invoked from a @RestController endpoint.

When i invoked the service from a camel route (again via the custom delegator) it barfed with a lazy initialization exception.

On digging, found that the service implements an interface, the custom delegator looks up the service (it is injected so has proper proxy) and calls a method on the interface which is actually a java-8 default method. This default-method then locally calls the @Transactional method.

So there's the problem :- this is a LOCAL method call so the aspecting/proxy-ing of the @Transactional annotation is not done (we use aspectJAutoProxy) so the method is NOT invoked within a transaction, so the lazy-loading SHOULD fail. And to double-check, also tried it via an @Scheduled annotation: same behaviour. Barfs like it should.

My Question: So why does it work when called from the @RestController? This is driving me nuts!

There is no transactional annotation on the rest controller endpoint.

I added some debug code to the service using TransactionSynchronizationManager.isActualTransactionActive() and it shows that in no case is there a transaction, even when being called via the controller endpoint.

So why does the lazy loading work when being called from the controller? I dumped all SQL and at no points are the lazy-collection already loaded, so they are not in any hibernate cache.

I remember reading once that lazy loading was a hint, not a command, but still... why does it work in that one case?

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

after being perplexed by this on many occasions, have stumbled across the answer:

sprint-boot is doing an open-entity-manager-in-view behind our backs via the OpenEntityManagerInView interceptor. Had no idea this was going on.

See this excellent answer from Vlad Mihalcea https://stackoverflow.com/a/48222934/208687

about 4 years ago · Santiago Trujillo Report

0

When your method annotate to transactional hibernate session close after return method , if object that return from method have lazy , lazy property not load and you get exception that session close. You can use fetch in query or using OSIV

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!