Type de récupération par défaut pour un-à-un, plusieurs-à-un et un-à-plusieurs dans Hibernate

103

Quel est le type de récupération par défaut dans les mappages d'hibernation?

Ce que j'ai appris après avoir exploré, c'est:

  • pour un contre un, il est impatient .
  • pour un à plusieurs, c'est paresseux .

Mais après l'avoir testé dans Eclipse, il était avide de tout.

Cela dépend-il du fait que j'utilise JPA ou Hibernate?

Richa
la source
1
Si vous êtes toujours impliqué dans les sujets JPA, j'ai mis à jour votre question avec une nouvelle réponse, car les anciennes sont obsolètes pour la version actuelle d'Hibernate.
Alexander Rühl

Réponses:

193

Cela dépend si vous utilisez JPA ou Hibernate.

À partir de la spécification JPA 2.0 , les valeurs par défaut sont:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

Et en hibernation, tout est paresseux

METTRE À JOUR:

La dernière version d'Hibernate s'aligne sur les valeurs par défaut JPA ci-dessus.

Ashish Agarwal
la source
11
"Et en veille prolongée, tout est paresseux" apparemment cela a changé dans les versions récentes. Veuillez consulter la réponse d'Alexander Rühl ci-dessous .
Dinei
1
Hibernate est l'une des implémentations de JPA, donc une fois que vous utilisez Hibernate, vous utilisez JPA :)
xenteros
Il s'agit d'une requête courante. @Ashish Agarwal Pouvez-vous mettre à jour la dernière ligne de votre réponse. Dans Hibernate, ce n'est pas paresseux pour tous maintenant.
Saurabh Tiwari
Mise à jour du message en ce qui concerne le dernier comportement Hibernate.
M Anouti le
Il y avait une mise à jour, affirmant que désireux est le type de récupération par défaut pour chaque mappage, qui est réfuté par le chapitre 11.3 dans la documentation actuelle 5.x et 6.x Hibernate, j'ai donc annulé la modification. En outre, il est contre la recommandation de ne pas avoir d'empressement automatique, car cela signifierait probablement sélectionner toute la base de données lors de la récupération d'un seul objet.
Alexander Rühl
51

Je sais que les réponses étaient correctes au moment de poser la question - mais comme les gens (comme moi cette minute) les trouvent encore se demandant pourquoi leur WildFly 10 se comportait différemment, j'aimerais vous donner une mise à jour pour l'actuel Hibernate 5 Version .x:

Dans le Guide de l'utilisateur d'Hibernate 5.2, cela est indiqué au chapitre 11.2. Application des stratégies de récupération :

La recommandation Hibernate est de marquer statiquement toutes les associations paresseuses et d'utiliser des stratégies de récupération dynamiques pour l'empressement. Ceci est malheureusement en contradiction avec la spécification JPA qui définit que toutes les associations un-à-un et plusieurs-à-un doivent être récupérées avec impatience par défaut . Hibernate, en tant que fournisseur JPA, respecte cette valeur par défaut.

Donc Hibernate se comporte également comme Ashish Agarwal indiqué ci-dessus pour JPA:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(voir la spécification JPA 2.1 )

Alexander Rühl
la source
Et si nous utilisons l'hibernation native au lieu de JPA impl, agit-il de la même manière?
jMounir
@jMounir: Eh bien, je n'ai pas essayé cela, mais comme Hibernate déclare qu'il se comporte comme défini dans JPA, je ne vois pas pourquoi cela différerait lors de l'utilisation d'Hibernate pour lui-même. On peut dans les deux cas remplacer la stratégie par défaut.
Alexander Rühl
15

Pour répondre à votre question, Hibernate est une implémentation de la norme JPA. Hibernate a ses propres bizarreries de fonctionnement, mais selon la documentation Hibernate

Par défaut, Hibernate utilise la récupération de sélection paresseuse pour les collections et la récupération de proxy différée pour les associations à valeur unique. Ces valeurs par défaut ont du sens pour la plupart des associations dans la majorité des applications.

Ainsi, Hibernate chargera toujours n'importe quel objet en utilisant une stratégie de récupération paresseuse, quel que soit le type de relation que vous avez déclaré. Il utilisera un proxy paresseux (qui devrait être non initialisé mais pas nul) pour un seul objet dans une relation un-à-un ou plusieurs-à-un, et une collection nulle qu'il hydratera avec des valeurs lorsque vous tenterez d'y accéder .

Il faut comprendre qu'Hibernate tentera de remplir ces objets avec des valeurs uniquement lorsque vous tenterez d'accéder à l'objet, sauf si vous le spécifiez fetchType.EAGER.

JamesENL
la source
0

Pour les associations à valeur unique, c'est-à-dire un-à-un et plusieurs-à-un: -
Par défaut Lazy = proxy
Chargement paresseux du proxy : - Cela implique qu'un objet proxy de votre entité associée est chargé. Cela signifie que seul l'identifiant reliant les deux entités est chargé pour l'objet proxy de l'entité associée.
Par exemple: A et B sont deux entités avec plusieurs à une association. ie: il peut y avoir plusieurs A pour chaque B. Chaque objet de A contiendra une référence de B.
`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
La relation A contiendra des colonnes (aide, offre, ... autres colonnes de l'entité A).
La relation B contiendra des colonnes (bid, ... autres colonnes de l'entité B)

Proxy implique que lorsque A est récupéré, seul id est récupéré pour B et stocké dans un objet proxy de B qui ne contient que id. L'objet proxy de B est un objet d'une classe proxy qui est une sous-classe de B avec seulement des champs minimaux. Puisque l'offre fait déjà partie de la relation A, il n'est pas nécessaire de lancer une requête pour obtenir une offre à partir de la relation B. Les autres attributs de l'entité B ne sont chargés paresseusement que lorsqu'un champ autre que bid est accédé.

Pour les collections, c'est-à-dire plusieurs-à-plusieurs et un-à-plusieurs: -
Par défaut Lazy = true


Veuillez également noter que la stratégie de récupération (sélection, jointure, etc.) peut remplacer lazy. ie: Si lazy = 'true' et fetch = 'join', la récupération de A va également chercher B ou Bs (dans le cas de collections). Vous pouvez obtenir la raison si vous y réfléchissez.
L'extraction par défaut pour une association à valeur unique est "join".
La récupération par défaut des collections est "select". Veuillez vérifier les deux dernières lignes. J'en ai déduit logiquement.

Jijo Mathew
la source