Ricerca…


Caricamento pigro vs caricamento Eager

Il recupero o il caricamento dei dati può essere principalmente classificato in due tipi: desideroso e pigro.

Per utilizzare Hibernate, assicurati di aver aggiunto l'ultima versione di esso alla sezione delle dipendenze del tuo file pom.xml:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>   
    <version>5.2.1.Final</version>
</dependency>

1. Caricamento Eager E Caricamento Lazy

La prima cosa di cui dovremmo discutere qui è quale carico pigro e caricamento avido sono:

Eager Loading è un modello di progettazione in cui l'inizializzazione dei dati avviene sul posto. Significa che le raccolte vengono recuperate completamente nel momento in cui viene prelevato il loro genitore (recupera immediatamente)

Lazy Loading è un modello di progettazione che viene utilizzato per rinviare l'inizializzazione di un oggetto fino al punto in cui è necessario. Questo può effettivamente contribuire alle prestazioni dell'applicazione.

2. Utilizzo dei diversi tipi di caricamento

Il caricamento lento può essere abilitato utilizzando il seguente parametro XML:

lazy="true"

Analizziamo l'esempio. Per prima cosa abbiamo una classe User:

public class User implements Serializable {
   
    private Long userId;
    private String userName;
    private String firstName;
    private String lastName;
    private Set<OrderDetail> orderDetail = new HashSet<>();

    //setters and getters
    //equals and hashcode
    }

Guarda il Set di orderDetail che abbiamo. Ora diamo un'occhiata alla classe OrderDetail :

public class OrderDetail implements Serializable {

    private Long orderId;
    private Date orderDate;
    private String orderDesc;
    private User user;

    //setters and getters
    //equals and hashcode
}

La parte importante che è coinvolta nell'impostazione del caricamento lazy in UserLazy.hbm.xml :

<set name="orderDetail" table="USER_ORDER" inverse="true" lazy="true" fetch="select">
    <key>
        <column name="USER_ID" not-null="true" />
    </key>
   <one-to-many class="com.baeldung.hibernate.fetching.model.OrderDetail" />
</set>

Questo è il modo in cui il caricamento lazy è abilitato. Per disabilitare il caricamento lazy possiamo semplicemente usare: lazy = "false" e questo a sua volta abiliterà il caricamento ansioso. Di seguito è riportato l'esempio dell'impostazione di caricamento ingerente in un altro file User.hbm.xml:

<set name="orderDetail" table="USER_ORDER" inverse="true" lazy="false" fetch="select">
    <key>
        <column name="USER_ID" not-null="true" />
    </key>
   <one-to-many class="com.baeldung.hibernate.fetching.model.OrderDetail" />
</set>

Scopo

Per coloro che non hanno giocato con questi due progetti, lo scopo di pigro e desideroso è all'interno di una sessione specifica di SessionFactory . Eager carica tutto all'istante, significa che non è necessario chiamare nulla per recuperarlo. Ma il recupero pigro di solito richiede qualche azione per recuperare raccolta / oggetto mappato. Questo a volte è problematico ottenere il recupero pigro al di fuori della sessione . Ad esempio, hai una vista che mostra i dettagli di alcuni POJO mappati.

@Entity
public class User {
    private int userId;
    private String username;
    @OneToMany
    private Set<Page> likedPage;

    // getters and setters here
}

@Entity
public class Page{
    private int pageId;
    private String pageURL;

    // getters and setters here
}

public class LazzyTest{
    public static void main(String...s){
        SessionFactory sessionFactory = new SessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        
        User user = session.get(User.class, 1);
        transaction.commit();
        session.close();
        
        // here comes the lazy fetch issue
        user.getLikedPage();
    }
}

Quando proverai a farti prendere pigro fuori dalla sessione , otterrai lazyinitializeException . Questo perché per impostazione predefinita la strategia di recupero per tutti oneToMany o qualsiasi altra relazione è lazy (chiamata su DB su richiesta) e quando si è chiusa la sessione, non si ha il potere di comunicare con il database. quindi il nostro codice cerca di recuperare la raccolta di LikePage e genera un'eccezione perché non esiste una sessione associata per il rendering del DB.

La soluzione per questo è usare:

  1. Apri Sessione in vista - In cui si mantiene aperta la sessione anche nella vista di rendering.
  2. Hibernate.initialize(user.getLikedPage()) prima della sessione di chiusura - Questo indica a Hibernate.initialize(user.getLikedPage()) di inizializzare gli elementi della raccolta


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow