Sobes.tech
Middle

Cosa significa FetchType.LAZY in JPA e come influisce sul caricamento delle entità correlate?

sobes.tech AI

Risposta dell'AI

FetchType.LAZY in JPA indica caricamento ritardato delle entità correlate. Invece di caricare l'intera collezione correlata o un'entità separata al recupero dell'entità principale, JPA crea un oggetto proxy. Il caricamento effettivo dei dati dal database avverrà solo al primo accesso ai campi o ai metodi del proxy.

Questo permette di:

  • Ottimizzare le prestazioni: Evitare di estrarre grandi volumi di dati dal database quando non sono necessari.
  • Ridurre il consumo di memoria: Caricare solo i dati necessari.

Per impostazione predefinita, per la maggior parte delle relazioni (@OneToMany, @ManyToMany) si utilizza FetchType.LAZY, mentre per @OneToOne e @ManyToOneFetchType.EAGER. È possibile specificare esplicitamente il tipo di caricamento:

// Esempio di utilizzo di FetchType.LAZY
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private Set<ChildEntity> children;

@ManyToOne(fetch = FetchType.LAZY)
private ParentEntity parent;

Problemi con FetchType.LAZY:

  • LazyInitializationException: Può verificarsi se si tenta di accedere a un'entità caricata in modo ritardato dopo che la sessione in cui è stata caricata è stata chiusa.
  • Problema N+1: Se si itera su una collezione di entità con caricamento ritardato e si accede a ogni entità correlata, verrà eseguita una query separata per ogni entità della collezione.

Per risolvere questi problemi, si può:

  • Ottenere esplicitamente i dati correlati usando JOIN FETCH in JPQL:

    // Esempio di JOIN FETCH
    SELECT p FROM ParentEntity p JOIN FETCH p.children WHERE p.id = :parentId
    
  • Configurazioni del provider JPA (ad esempio, usando batching).

  • Annotazione @Fetch(FetchMode.JOIN) o @Fetch(FetchMode.SELECT) in Hibernate.