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 SessionDoğ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
MultipleBagFetchExceptionyaratabilir;@BatchSizeveya 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'dafalseyapılması önerilir. hibernate.enable_lazy_load_no_trans: her lazy erişimde yeni bağlantı açar, anti-pattern'dir.
İlgili Java & Spring soruları
- Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?
- ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?
- @Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.
- Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?
- Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?
- Java'da Garbage Collection nasıl çalışır? G1 ve ZGC arasındaki farklar nelerdir, hangisini ne zaman seçersiniz?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.