web-dev-qa-db-fra.com

Qu'est-ce que le chargement paresseux dans Hibernate?

Qu'est-ce que le chargement paresseux en Java? Je ne comprends pas le processus. Quelqu'un peut-il m'aider à comprendre le processus de chargement paresseux?

161
rocker

Supposons que vous ayez un parent et que ce parent ait une collection d'enfants. Hibernate peut maintenant "charger paresseux" les enfants, ce qui signifie qu'il ne charge pas réellement tous les enfants lors du chargement du parent. Au lieu de cela, il les charge à la demande. Vous pouvez le demander explicitement ou, ce qui est beaucoup plus courant, hibernate les chargera automatiquement lorsque vous tenterez d'accéder à un enfant.

Le chargement paresseux peut aider à améliorer les performances de manière significative car souvent vous n’avez pas besoin des enfants et ils ne seront donc pas chargés.

Méfiez-vous également du problème n + 1. Hibernate ne charge pas tous les enfants lorsque vous accédez à la collection. Au lieu de cela, il chargera chaque enfant individuellement. Lorsque vous parcourez la collection, cela provoque une requête pour chaque enfant. Pour éviter cela, vous pouvez faire en sorte que Hibernate charge tous les enfants simultanément, par exemple. en appelant parent.getChildren (). size ().

255
Thomas Lötzer

"Chargement paresseux" signifie qu'une entité sera chargée uniquement lorsque vous accéderez réellement à l'entité pour le première fois.

Le motif est comme ceci:

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

Cela évite au préalable le coût du préchargement/pré-remplissage de toutes les entités d'un ensemble de données volumineux alors que vous n'avez finalement pas besoin de all . d'eux.

Dans Hibernate, vous pouvez configurer le chargement paresseux d'une collection d'entités enfants. Le chargement paresseux réel est ensuite effectué dans les méthodes de PersistentSet qu'Hibernate utilise "sous le capot" pour attribuer la collection. des entités comme Set.

Par exemple.

public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}

.

public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}
71
BalusC

Martin Fowler définit le Lazy Load pattern dans Patterns of Enterprise Application Architecture en tant que tel:

Un objet qui ne contient pas toutes les données dont vous avez besoin mais qui sait comment l'obtenir.

Ainsi, lors du chargement d'un objet donné, l'idée est de ne pas charger eager les objets associés que vous ne pouvez pas utiliser immédiatement pour économiser le coût de performances associé. Au lieu de cela, le ou les objets associés ne seront chargés que s’ils sont utilisés. 

Il ne s'agit pas d'un modèle spécifique à l'accès aux données et à Hibernate, mais il est particulièrement utile dans de tels domaines et Hibernate prend en charge le chargement paresseux d'associations un à plusieurs et d'associations à point unique (un à un et plusieurs à un) également. sous certaines conditions. Les interactions paresseuses sont décrites plus en détail dans Chapitre 19 de la documentation de référence d'Hibernate 3.0. 

24
Pascal Thivent

Par défaut, le chargement paresseux est true. Le chargement par carrure signifie que lorsque la requête de sélection est exécutée, elle ne frappe pas la base de données. Il attendra la fonction getter, c’est-à-dire que nous aurons besoin de la base de données . Par exemple: Vous êtes un parent qui a un enfant avec beaucoup de jouets. Mais le problème actuel est que, chaque fois que vous l'appelez (nous supposons que vous avez un garçon), il vient à vous avec tous ses jouets. Maintenant, c'est un problème puisque vous ne voulez pas qu'il porte tout le temps ses jouets… Donc, en tant que parent responsable, vous allez de l'avant et définissez les jouets de l'enfant comme étant LAZY. Maintenant, chaque fois que vous l'appelez, il vient à vous sans ses jouets.

15
Chandresh Solanki

Lazy La recherche détermine si les objets enfants doivent être chargés lors du chargement de l'objet parent. Vous devez définir ce fichier de mappage hibernate correspondant à la classe parente. Lazy = true (signifie ne pas charger l'enfant) Par défaut, le chargement paresseux des objets enfants est vrai. 

Cela garantit que les objets enfants ne sont pas chargés, sauf s'ils sont explicitement appelés dans l'application en appelant la méthode getChild() sur le parent. Dans ce cas, hibernate émet un nouvel appel à la base de données pour charger l'enfant lorsque getChild() est appelé de manière autonome sur l'objet Parent.

Mais dans certains cas, vous devez charger les objets enfants lorsque le parent est chargé. Faites juste lazy = false et hibernate chargera l’enfant quand le parent est chargé depuis la base de données.

Exemple: Si vous avez une table? EMPLOYEE est mappé sur l'objet Employee et contient un ensemble d'objets Address. Classe de parent: Classe d'employé, Classe d'enfant: Classe d'adresse 

public class Employee { 
private Set address = new HashSet(); // contains set of child Address objects 
public Set getAddress () { 
return address; 
} 
public void setAddresss(Set address) { 
this. address = address; 
} 
} 

Dans le fichier Employee.hbm.xml 

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

Dans la configuration ci-dessus. Si lazy="false": - lorsque vous chargez l'objet Employé, l'adresse de l'objet enfant Time est également chargée et définie sur la méthode setAddresss (). Si vous appelez employee.getAdress (), les données renvoyées sont chargées. Aucun appel de base de données récent. 

Si lazy="true": - Ceci est la configuration par défaut. Si vous ne parlez pas, mettez en veille prolongée, considérez lazy = true. lorsque vous chargez l'objet Employé alors que l'objet enfant Heure, l'adresse n'est pas chargé. Vous avez besoin d'un appel supplémentaire à la base de données pour obtenir des objets d'adresse. Si vous appelez employee.getAdress(), la requête de base de données heure est déclenchée et renvoie les résultats. Appel de base de données frais.

11
Bhavin Shah

En langage profane, c'est comme si vous prépariez un gâteau et que vous aurez besoin de 5 à 10 ingrédients du réfrigérateur. Vous avez deux options: obtenir tous les ingrédients du réfrigérateur et les déposer sur la plateforme de votre cuisine ou apporter l'élément de votre choix quand vous en avez besoin.

De même, lors du chargement avec impatience, vous récupérez toutes les informations sur le haricot et ses classes associées (pas de relation enfant ou is-a mais une relation, par exemple un gâteau a vous apportez uniquement son identifiant et les valeurs qui proviennent de la même table (ingrédients nécessaires dont vous aurez besoin en premier dans votre bol en cas de gâteau). Toutes les informations provenant d'autres tables seront récupérées au fur et à mesure des besoins/utilisations.

8
Keyur

Chargement paresseux? Cela signifie simplement que les enregistrements enfants ne sont pas récupérés immédiatement, mais automatiquement dès que vous essayez d'y accéder.

8
Steffen

Le paramètre différé décide de charger ou non les objets enfants lors du chargement de l'objet parent. Ce fichier de mappage d'hibernation correspondant à la classe parente doit être paramétré.Lazy = true (signifie ne pas charger l'enfant) Par défaut, le chargement différé des objets enfants est true. . Cela garantit que les objets enfants ne sont pas chargés sauf s'ils sont explicitement appelés dans l'application en appelant la méthode getChild () sur parent. Dans ce cas, hibernate émet un nouvel appel à la base de données pour charger l'enfant lorsque getChild () est appelé sur le parent. object.Mais dans certains cas, vous devez charger les objets enfants lorsque le parent est chargé. Faites juste lazy = false et hibernate chargera l’enfant quand le parent est chargé depuis la base de données.Exampleslazy = true (par défaut) L’adresse enfant de la classe User peut être relâchée s’il n’est pas requis fréquemment. l'objet Author pour Book parent chaque fois que vous utilisez le livre pour la librairie en ligne.

3
Siva Chimpiri

Le chargement paresseux est un motif de conception couramment utilisé en programmation informatique reporter l'initialisation d'un objet jusqu'au point où il est nécessaire . Cela peut contribuer à l’efficacité dans le le fonctionnement du programme si correctement et utilisé de manière appropriée 

Wikipédia

Lien de Chargement paresseux de hibernate.org

2
Diego Dias

Cela signifie simplement que vous devez charger les données dont vous avez besoin au lieu de charger toutes sortes de données à la fois que vous n'utiliserez pas maintenant. Ainsi, le temps de chargement de l'application est plus rapide que d'habitude. 

0
Abhinaya Pandey

Le chargement différé vous permet de différer la récupération d'association ou de mieux contrôler la stratégie d'extraction.

Lorsque vous utilisez le chargement EAGER, vous définissez un plan d'extraction global qui ne peut pas être remplacé au moment de l'interrogation, ce qui signifie que vous êtes limité à une décision que vous avez prise lors de la conception de votre modèle d'entité. L'extraction EAGER est une odeur de code , car la stratégie d'extraction est une stratégie au moment de l'interrogation et peut varier d'un cas d'utilisation à l'autre.

La stratégie d’extraction est un aspect très important, car trop d’extraction dans EAGER peut entraîner de graves problèmes de performances.

0
Vlad Mihalcea

Hiberante prend en charge la fonctionnalité d'initialisation différée pour les entités et les collections . Le moteur Hibernate ne charge que les objets que nous interrogeons, pas d'autres entités ou collections.

 

lazy = "false" par défaut, le chargement mentionne pour le seul enfant est lazy.in cas où true est chargé que le parent est en charge ne prend pas en charge l'enfant

0
abburi

Le paramètre différé décide de charger ou non les objets enfants lors du chargement de l'objet parent. Ce fichier de mappage d'hibernation correspondant à la classe parente doit être paramétré.Lazy = true (signifie ne pas charger l'enfant) Par défaut, le chargement différé des objets enfants est true. .

0

Étonnamment, aucune des réponses ne parle de la manière dont cela est réalisé en veille prolongée derrière les écrans.

Chargement paresseux est un modèle de conception utilisé avec succès en veille prolongée pour des raisons de performances, qui implique le suivi de techniques.


1. Instrumentation du code d'octet

Améliore la définition de la classe de base avec hibernate hooks pour intercepter tous les appels de cet objet entité.

Fait soit au moment de la compilation ou du temps de [chargement]

1.1 temps de compilation

  • Opération post-compilation

  • Principalement par les plugins maven/ant

1.2 Durée

  • Si aucune instrumentation au moment de la compilation n'est effectuée, celle-ci est créée au moment de l'exécution Utiliser des bibliothèques comme javassist

2. Proxies

Les objets Entité renvoyés par Hibernate sont des proxy du type réel.

Voir aussi: Javassist. Quelle est l'idée principale et où l'utilisation réelle?

0