Question

À partir de l’API, j’ai pu constater que cela avait quelque chose à voir avec le proxy. Mais je n'ai pas trouvé beaucoup d'informations sur le proxy et je ne comprends pas la différence entre appeler session.get et session.load . Quelqu'un pourrait-il m'expliquer ou me diriger vers une page de référence?

Merci !!

Était-ce utile?

La solution

Depuis le forum d'Hibernate :

  

Ceci est extrait du livre Hibernate in Action. Bon on a lu ça ..

Récupération des objets par identifiant L'extrait de code Hibernate suivant récupère un objet Utilisateur de la base de données:

User user = (User) session.get(User.class, userID);

La méthode get () est spéciale car l'identifiant identifie de manière unique un seul instance d'une classe. C’est pourquoi il est courant que les applications utilisent cet identifiant en tant que poignée commode à un objet persistant. La récupération par identifiant peut utiliser le cache lors de la récupération d'un objet, éviter une frappe de base de données si l'objet est déjà mis en cache. Hibernate fournit également une méthode load ():

User user = (User) session.load(User.class, userID);

La méthode load () est ancienne; get () a été ajouté à l'API d'Hibernate en raison de l'utilisateur demande. La différence est triviale:

Si load () ne peut pas trouver l'objet dans le cache ou la base de données, une exception est jeté. La méthode load () ne renvoie jamais la valeur null. La méthode get () renvoie NULL si l'objet ne peut pas être trouvé.

La méthode load () peut renvoyer un proxy au lieu d'une instance persistante réelle. Un proxy est un espace réservé qui déclenche le chargement de l'objet réel lorsque celui-ci est activé. accédé pour la première fois; Sur le D'autre part, get () ne retourne jamais un proxy. Choisir entre get () et load () est simple: si vous êtes certain de la persistance l'objet existe, et la non-existence serait considérée comme exceptionnelle, load () est un bonne option. Si vous n'êtes pas certain, il existe une instance persistante avec le paramètre donné. identificateur, utilisez get () et testez la valeur de retour pour voir si elle est nulle. Utiliser load () a autre implication: l’application peut récupérer une référence valide (un proxy) vers un instance persistante sans frapper la base de données pour récupérer son état persistant. Alors load () peut ne pas lancer d’exception s’il ne trouve pas l’objet persistant dans le cache ou la base de données; l'exception serait levée plus tard, lorsque le proxy est accédé. Bien sûr, récupérer un objet par identifiant n’est pas aussi flexible que d’utiliser arbitraire requêtes.

Autres conseils

Eh bien, pour nhibernate au moins, session.Get (id) chargera l’objet à partir de la base de données, alors que session.Load (id) ne créera qu’un objet proxy sans quitter votre serveur. Fonctionne comme toute autre propriété chargée paresseux dans vos POCO (ou POJO :). Vous pouvez ensuite utiliser ce proxy comme référence à l'objet lui-même pour créer des relations, etc.

Pensez-y comme si vous aviez un objet qui ne garde que l'identifiant et chargera le reste si vous en avez besoin. Si vous ne faites que le transmettre pour créer des relations (comme des FK), l’identifiant est tout ce dont vous aurez besoin.

session.load () retournera toujours un “proxy” (terme Hibernate) sans toucher à la base de données. Dans Hibernate, proxy est un objet avec la valeur d'identifiant donnée, ses propriétés ne sont pas encore initialisées, cela ressemble à un faux objet temporaire.     Si aucune ligne n'est trouvée, une exception ObjectNotFoundException sera lancée.

session.get () frappe toujours la base de données et renvoie l'objet réel, un objet représentant la ligne de la base de données, et non un proxy.     Si aucune ligne n'est trouvée, elle renvoie la valeur null.

Les performances avec ces méthodes font aussi diff. entre deux ...

Encore un point extra ::

La méthode get de la classe Hibernate Session renvoie la valeur null si l'objet n'est pas trouvé dans le cache ni dans la base de données. La méthode load () lève une exception ObjectNotFoundException si l'objet n'est pas trouvé dans le cache ni dans la base de données, mais ne renvoie jamais la valeur null.

Une conséquence indirecte de l’utilisation de "load" au lieu de " get " est ce verrouillage optimiste en utilisant un attribut de version peut ne pas fonctionner comme prévu. Si un chargement crée simplement un proxy et ne lit pas à partir de la base de données, la propriété version n'est pas chargée. La version ne sera chargée que lorsque / si vous vous référez ultérieurement à une propriété de l'objet, ce qui déclenche une sélection. Entre-temps, une autre session peut mettre à jour l'objet et votre session n'aura pas la version d'origine dont elle a besoin pour effectuer la vérification de verrouillage optimiste - la mise à jour de votre session remplacera donc la mise à jour de l'autre session sans aucun avertissement.

Voici une tentative d’esquisse de ce scénario avec deux sessions utilisant un objet avec le même identifiant. La version initiale de l'objet dans la base de données est 10.

Session 1                  Session 2
---------                  ---------
Load object
Wait a while..   
                           Load object
                           Modify object property
                           [triggers db 'select' -
                            version read as 10]
                           Commit
                           [triggers db update,
                            version modified to 11]
Modify object property
  [triggers db 'select' -
  version read as 11]
Commit
  [triggers db update,
  version modified to 12]

Nous voulons réellement que la validation de la session 1 échoue avec une exception de verrouillage optimiste, mais elle réussira ici.

Utilisation de " get " au lieu de " charger " contourne le problème, car get émettra immédiatement un select et les numéros de version seront chargés au bon moment pour la vérification du verrouillage optimiste.

Nous devons également faire attention lorsque nous utilisons load car cela lève une exception si l'objet n'est pas présent. Nous ne devons l'utiliser que lorsque nous sommes sûrs que cet objet existe.

Vous trouverez une excellente explication à l'adresse http: //. www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Il renverra toujours un & proxy # 8220; & # 8221; (Terme Hibernate) sans toucher à la base de données.
Dans Hibernate, le proxy est un objet avec la valeur d'identificateur donnée, ses propriétés ne sont pas encore initialisées, il ressemble simplement à un faux objet temporaire.
Il retournera toujours un objet proxy avec la valeur d'identité donnée, même si la valeur d'identité n'existe pas dans la base de données. Toutefois, lorsque vous essayez d’initialiser un proxy en récupérant les propriétés de la base de données, il va toucher la base de données avec l’instruction select. Si aucune ligne n'est trouvée, une exception ObjectNotFoundException sera levée.
session.get ():
Il frappe toujours la base de données (s'il ne se trouve pas dans le cache) et renvoie l'objet réel, un objet représentant la ligne de la base de données, et non un proxy.
Si aucune ligne n'est trouvée, elle renvoie la valeur null.

load () ne peut pas trouver l'objet dans le cache ou la base de données, une exception est levée et la méthode load () ne renvoie jamais la valeur null.

La méthode get () renvoie la valeur null si l’objet ne peut pas être trouvé. La méthode load () peut renvoyer un proxy au lieu d'une instance persistante réelle. Get () ne renvoie jamais un proxy.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top