JPA/Hibernate'te lazy ve eager loading farkı nedir? LazyInitializationException neden oluşur ve nasıl çözülür?

Cevap

  • Lazy loading: ilişkili veri ilk erişildiği anda ayrı bir sorguyla yüklenir; Hibernate gerçek nesne yerine bir proxy koyar.
  • Eager loading: ana entity ile birlikte hemen yüklenir.

JPA varsayılanları: @OneToMany ve @ManyToMany LAZY; @ManyToOne ve @OneToOne EAGER. Pratikte önerilen, her ilişkiyi LAZY yapıp ihtiyaç olan sorguda açıkça fetch etmektir; EAGER gizli N+1 sorgularına yol açar.

LazyInitializationException

Lazy proxy'nin yüklenmesi için açık bir persistence context (Session) gerekir. Transaction bittikten sonra (örneğin controller'da veya JSON serialization sırasında) koleksiyona erişirseniz:

org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: Order.items, could not initialize proxy - no Session

Doğru çözümler

// 1) JOIN FETCH
@Query("select o from Order o join fetch o.items where o.id = :id")
Optional<Order> findWithItems(@Param("id") Long id);

// 2) EntityGraph
@EntityGraph(attributePaths = {"items", "customer"})
List<Order> findByStatus(OrderStatus status);

// 3) DTO projection: yalnızca gereken alanlar
@Query("select new com.app.OrderSummary(o.id, o.total) from Order o")
List<OrderSummary> summaries();
  • Entity yerine DTO döndürmek, serialization sırasında lazy alanlara kazara erişilmesini de engeller.
  • Birden fazla koleksiyonu aynı anda join fetch etmek kartezyen çarpım ve MultipleBagFetchException yaratabilir; @BatchSize veya ayrı sorgular kullanın.

Kaçınılması gerekenler

  • Open Session in View (spring.jpa.open-in-view, Spring Boot'ta varsayılan true ve başlangıçta uyarı verir): sorunu gizler, DB bağlantısını view render edilene kadar tutar. Production'da false yapılması önerilir.
  • hibernate.enable_lazy_load_no_trans: her lazy erişimde yeni bağlantı açar, anti-pattern'dir.
  1. Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?OrtaJava & SpringBackend
  2. ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?OrtaJava & SpringBackend
  3. @Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.ZorJava & SpringBackend
  4. Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?KolayJava & SpringBackend
  5. Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?KolayJava & SpringBackend
  6. Java'da Garbage Collection nasıl çalışır? G1 ve ZGC arasındaki farklar nelerdir, hangisini ne zaman seçersiniz?ZorJava & SpringBackend

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle