Zoeken…


Lazy Loading versus Eager Loading

Het ophalen of laden van gegevens kan voornamelijk in twee soorten worden ingedeeld: enthousiast en lui.

Om Hibernate te gebruiken, moet je de nieuwste versie ervan toevoegen aan de afhankelijkheden van je pom.xml-bestand:

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

1. Enthousiast laden en lui laden

Het eerste dat we hier moeten bespreken, is wat lui laden en enthousiast laden zijn:

Eager Loading is een ontwerppatroon waarbij data-initialisatie ter plaatse plaatsvindt. Het betekent dat collecties volledig worden opgehaald op het moment dat hun ouder wordt opgehaald (direct ophalen)

Lazy Loading is een ontwerppatroon dat wordt gebruikt om de initialisatie van een object uit te stellen tot het moment waarop het nodig is. Dit kan effectief bijdragen aan de prestaties van de applicatie.

2. Gebruik van de verschillende soorten laden

Lazy laden kan worden ingeschakeld met behulp van de volgende XML-parameter:

lazy="true"

Laten we het voorbeeld nader bekijken. Eerst hebben we een gebruikersklasse:

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
    }

Bekijk de Set of orderDetail die we hebben. Laten we nu eens kijken naar de klasse OrderDetail :

public class OrderDetail implements Serializable {

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

    //setters and getters
    //equals and hashcode
}

Het belangrijke onderdeel dat betrokken is bij het instellen van de luie lading 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>

Dit is hoe het luie laden is ingeschakeld. Om lui laden uit te schakelen, kunnen we eenvoudig gebruiken: lazy = "false" en dit zal op zijn beurt gretig laden mogelijk maken. Hier volgt een voorbeeld van het instellen van enthousiast laden in een ander bestand 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>

strekking

Voor degenen die niet met deze twee ontwerpen hebben gespeeld, ligt de reikwijdte van lui en enthousiast in een specifieke Session of SessionFactory . Eager laadt alles meteen, wat betekent dat u niets hoeft te bellen om het op te halen. Maar lui ophalen vereist meestal enige actie om toegewezen collectie / object op te halen. Dit is soms problematisch om lui te worden buiten de sessie . U hebt bijvoorbeeld een weergave die het detail van de toegewezen POJO toont.

@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();
    }
}

Wanneer je buiten de sessie lui probeert te worden, krijg je de lazyinitializeException . Dit komt omdat standaard de ophaalstrategie voor alle oneToMany of een andere relatie lui is (oproep naar DB op aanvraag) en wanneer u de sessie hebt gesloten, hebt u geen macht om met de database te communiceren. dus onze code probeert de verzameling likesPage op te halen en genereert een uitzondering omdat er geen gekoppelde sessie is voor het weergeven van DB.

Oplossing hiervoor is om te gebruiken:

  1. Sessie in weergave openen - waarin u de sessie zelfs op de weergegeven weergave open houdt.
  2. Hibernate.initialize(user.getLikedPage()) voor het beëindigen van de sessie - Dit vertelt hibernate de collectie-elementen te initialiseren


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow